Подтвердить что ты не робот

Срок действия директив 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
    });
}

Возможно, я мог бы посмотреть некоторую переменную в области видимости, но я не знаю, какую переменную нужно наблюдать.

Итак, как я могу быть уведомлен о том, когда изменяется модель действия?

4b9b3361

Ответ 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.