Улучшить эту документациюФормы
Контролы (input, select, textarea) — это способы ввода данных пользователем. Форма — это набор элементов управления, предназначенный для группирования взаимосвязанных контролов.
Формы и элементы управления предоставляют службы валидации, чтобы пользователь мог получить уведомление о некорректном вводе до отправки формы. Это обеспечивает лучший пользовательский интерфейс, чем только валидация на стороне сервера, потому что пользователь получает мгновенную обратную связь о том, как исправить ошибку. Помните, что хотя валидация на стороне клиента играет важную роль в обеспечении хорошего пользовательского опыта, ее легко обойти, поэтому ей нельзя доверять. Для защищенного приложения все равно необходима валидация на стороне сервера.
Простая форма
Ключевым директивой для понимания двусторонней привязки данных является ngModel. Директива ngModel обеспечивает двустороннюю привязку данных, синхронизируя модель с представлением, а также представление с моделью. Кроме того, она предоставляет API для других директив для дополнения её поведения.
Обратите внимание, что novalidate используется для отключения собственной валидации формы браузера.
Значение ngModel не будет установлено, если оно не пройдёт валидацию для поля ввода. Например: поля ввода типа email должны иметь значение в формате user@domain.
Использование CSS-классов
Для стилизации формы и элементов управления директива ngModel добавляет следующие CSS-классы:
-
ng-valid: модель валидна -
ng-invalid: модель невалидна -
ng-valid-[key]: для каждого валидного ключа, добавленного$setValidity -
ng-invalid-[key]: для каждого невалидного ключа, добавленного$setValidity -
ng-pristine: с элементом управления ещё не взаимодействовали -
ng-dirty: с элементом управления взаимодействовали -
ng-touched: элемент управления потерял фокус -
ng-untouched: элемент управления не потерял фокус -
ng-pending: любые$asyncValidatorsне выполнены
Следующий пример использует CSS для отображения валидности каждого элемента управления формой. В примере оба user.name и user.email являются обязательными, но отображаются с красным фоном только после того, как ввод потеряет фокус. Это гарантирует, что пользователь не отвлекается на ошибку до взаимодействия с элементом управления и его невалидности.
Привязка к состоянию формы и элемента управления
Форма — это экземпляр FormController. Экземпляр формы можно необязательно опубликовать в область видимости, используя атрибут name.
Аналогично, элемент управления вводом, у которого есть директива ngModel, содержит экземпляр NgModelController. Такой экземпляр элемента управления можно опубликовать в качестве свойства экземпляра формы, используя атрибут name на элементе управления вводом. Атрибут name указывает имя свойства в экземпляре формы.
Это означает, что внутреннее состояние как формы, так и элемента управления доступно для привязки в представлении с использованием стандартных примитивов привязки.
Это позволяет нам расширить приведенный выше пример следующими функциями:
- Пользовательское сообщение об ошибке отображается после взаимодействия пользователя с элементом управления (то есть, когда
$touchedустановлено) - Пользовательское сообщение об ошибке отображается при отправке формы (
$submittedустановлено), даже если пользователь не взаимодействовал с элементом управления
Настройка триггеров обновления модели
По умолчанию любое изменение содержимого запускает обновление модели и валидацию формы. Вы можете переопределить это поведение, используя директиву ngModelOptions, чтобы привязаться только к указанному списку событий. То есть ng-model-options="{ updateOn: 'blur' }" будет обновлять и проверять только после того, как элемент управления потеряет фокус.
Вы можете установить несколько событий, используя список, разделенный пробелами. То есть ng-model-options="{ updateOn: 'mousedown blur' }"
Если вы хотите сохранить стандартное поведение и просто добавить новые события, которые могут инициировать обновление и валидацию модели, добавьте «default» в качестве одного из указанных событий.
Например, ng-model-options="{ updateOn: 'default blur' }"
Следующий пример показывает, как переопределить мгновенные обновления. Изменения в элементах управления внутри формы будут обновлять модель только при потере фокуса элементом управления (событие blur).
Немедленные (с задержкой) обновления модели
Вы можете отложить обновление/валидацию модели, используя ключ debounce с директивой ngModelOptions. Эта задержка также будет применена к парсерам, валидаторам и флагам модели, таким как $dirty или $pristine.
То есть ng-model-options="{ debounce: 500 }" будет ожидать полсекунды после последнего изменения содержимого, прежде чем инициировать обновление модели и валидацию формы.
Если используются пользовательские триггеры, пользовательские таймауты с задержкой можно установить для каждого события, используя объект в debounce. Это может быть полезно для принудительного вызова немедленных обновлений в определенных обстоятельствах (например, событиях blur).
Например, ng-model-options="{ updateOn: 'default blur', debounce: { default: 500, blur: 0 } }"
Если эти атрибуты добавлены к элементу, они будут применены ко всем дочерним элементам и контролам, унаследованным от него, если они не переопределены.
В этом примере показано, как выполнить задержку изменений модели. Модель будет обновлена только через 250 миллисекунд после последнего изменения.
Пользовательская валидация
AngularJS предоставляет базовые реализации для наиболее распространённых HTML5 типов input: (text, number, url, email, date, radio, checkbox), а также некоторые директивы для валидации (required, pattern, minlength, maxlength, min, max).
С помощью пользовательской директивы можно добавить собственные функции валидации в объект $validators на ngModelController. Для получения контроллера вам необходимо его указать в директиве, как показано в примере ниже.
Каждая функция в объекте $validators получает modelValue и viewValue в качестве параметров. Затем AngularJS вызовет $setValidity внутри с возвращаемым значением функции (true: валидно, false: невалидно). Функции валидации выполняются каждый раз при изменении ввода (вызывается $setViewValue), или когда изменяется привязанное значение model. Валидация происходит после успешного выполнения $parsers и $formatters, соответственно. Неуспешные валидаторы хранятся по ключу в ngModelController.$error.
Кроме того, существует объект $asyncValidators, который обрабатывает асинхронную валидацию, такую как выполнение запроса $http на бэкенд. Функции, добавленные в объект, должны возвращать промис, который должен быть resolved при валидности или rejected при невалидности. Продолжающиеся асинхронные валидации хранятся по ключу в ngModelController.$pending.
В следующем примере мы создаем две директивы:
-
Директива
integer, которая проверяет, является ли вход валидным целым числом. Например,1.23является невалидным значением, так как содержит дробную часть. Обратите внимание, что мы проверяем viewValue (строковое значение элемента управления), а не modelValue. Это связано с тем, что input[number] преобразует viewValue в число при выполнении$parsers. -
Директива
username, которая асинхронно проверяет, не занято ли введённое значение. Мы моделируем запрос к серверу с помощью промиса$q.
Изменение встроенных валидаторов
Поскольку сам AngularJS использует $validators, вы можете легко заменить или удалить встроенные валидаторы, если это необходимо. Следующий пример показывает, как перезаписать валидатор электронной почты в input[email] из пользовательской директивы, чтобы он требовал наличия определённого доменного имени верхнего уровня example.com . Обратите внимание, что вы можете альтернативно использовать ng-pattern для дальнейшего ограничения валидации.
Реализация пользовательских элементов управления формой (с использованием ngModel)
AngularJS реализует все основные элементы управления HTML-формой (input, select, textarea), что должно быть достаточно для большинства случаев. Однако, если вам нужна большая гибкость, вы можете написать собственный элемент управления формой в виде директивы.
Для того, чтобы пользовательский элемент управления работал с ngModel и для достижения двусторонней привязки, он должен:
- реализовать метод
$render, который отвечает за отображение данных после прохожденияNgModelController.$formatters, - вызвать метод
$setViewValueвсякий раз, когда пользователь взаимодействует с элементом управления, и модель должна быть обновлена. Это обычно выполняется внутри обработчика события DOM.
См. $compileProvider.directive для получения дополнительной информации.
Следующий пример демонстрирует, как добавить двустороннюю привязку данных к элементам contentEditable.
© 2010–2020 Google, Inc.
Licensed under the Creative Commons Attribution License 3.0.
https://code.angularjs.org/1.8.2/docs/guide/forms