Срок действия директив AngularJS
Я пытаюсь создать директиву, которая должна отображать некоторые действия, когда поле ввода помечено как недействительное. В этом примере допустим, что у меня есть директива, которая проверяет, является ли ввод простым числом, и я хочу создать директиву, которая добавляет класс к элементу, когда он недействителен:
<input type="text" ng-model="primeNumber" validate-prime invalid-add-class="error">
Validate-prime использует синтаксические анализаторы и форматирование на ng-модели для обновления действительности модели.
Теперь я хочу, чтобы директива invalid-add-class добавляла класс "ошибка", когда модель недействительна, и удалять ее, когда она действительна. Другими словами, он должен смотреть свойство $valid (или $invalid) контроллера модели. Однако я не могу понять, как это сделать. Я пробовал:
link : function(scope, element, attrs, ctrl) {
ctrl.$watch("$valid", function(newVal, oldVal) {
//never fired
});
}
Возможно, я мог бы посмотреть некоторую переменную в области видимости, но я не знаю, какую переменную нужно наблюдать.
Итак, как я могу быть уведомлен о том, когда изменяется модель действия?
Ответы
Ответ 1
Если у вас есть <form>
, добавьте к нему name
(допустим 'myForm') и name
на ваш вход (допустим myInput
). Вы должны иметь возможность $watch
:
scope.$watch('myForm.myInput.$valid', function(validity) {})
Если у вас нет form
, вы всегда можете наблюдать за функцией. Таким образом:
scope.$watch(function() { return ctrl.$valid; }, function(validity){});
Подробнее о подходе формы здесь.
Ответ 2
Если у вас нет <form />
, вы можете легко получить его:
В определении вашей директивы:
require: '^form'
а затем в вашей функции связи форма передается как четвертый параметр:
link: function (scope, element, attr, ctrl) {
Теперь вам не нужно жестко закодировать форму или поле ввода для выполнения $watch:
scope.$watch(ctrl.$name + '.' + element.attr('name') + '.$valid',
function (validity) {});
Ответ 3
Наша цель, в общем, должна заключаться в том, чтобы сделать директивную работу независимо от какой-либо одной формы или ввода. Как мы можем разрешить ему читать локальное свойство $valid
без обязательной привязки его к одной конкретной форме и имени ввода?
Просто используйте require: 'ngModel'
как одно из свойств вашей директивы config. Это добавит локальный контроллер ngModel в качестве четвертого аргумента функции связи, и вы можете поместить $watch
непосредственно на $valid
, не связывая реализацию директивы с какой-либо конкретной формой или вводом.
require: 'ngModel',
link: function postLink(scope, element, attrs, controller) {
scope.inputCtrl = controller;
scope.$watch('inputCtrl.$valid', handlerFunc)
}
Обработчик должен постоянно запускать изменения в $valid с этой структурой. См. этот скрипт, где вход подтвержден для шаблона почтового индекса U.S. или Zip + 4. Вы будете получать предупреждение каждый раз, когда будут изменены действительность.
РЕДАКТИРОВАТЬ 3/21/14: Этот пост ранее был зависшим от моего заблуждения, фиксируя неправильную причину проблемы реализации. Моя вина. В приведенном выше примере удаляется эта фиксация. Кроме того, добавлена скрипка, показывающая, что этот подход действительно работает и всегда выполнялся, как только вы добавляете кавычки вокруг выражения watch.