2013-04-09 4 views
29

Я пытаюсь создать директиву, которая должна отображать некоторые действия, когда поле ввода помечено как недействительное. Для этого примера предположим, у меня есть директива, которая проверяет, является ли входной простое число, и я хочу, чтобы создать директиву, которая добавляет класс к элементу, когда оно недействительно иAngularJS директива вахты действительность

<input type="text" ng-model="primeNumber" validate-prime invalid-add-class="error"> 

При проверке премьер ИСПОЛЬЗУЕТ парсеров и форматировщиков на ng-модели для обновления действительности модели.

Теперь я хочу, чтобы директива invalid-add-class добавляла класс «ошибка», когда модель недействительна, и удалять ее, когда она действительна. Другими словами, он должен смотреть свойство $ valid (или $ invalid) контроллера модели. Однако я не могу понять, как это сделать. Я пробовал:

link : function(scope, element, attrs, ctrl) { 
    ctrl.$watch("$valid", function(newVal, oldVal) { 
    //never fired 
    }); 
} 

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

Итак, как я могу получать уведомления о том, когда меняются действительность модели?

+0

если вы можете поделиться своей директивой, это будет хорошо! –

+0

Я не помню, для чего я это использовал, но второе решение CaioToOn уже почти полностью задействовано. Только тело второй функции должно быть заполнено любым действием, которое вы хотите, с изменением действительности. – Tiddo

ответ

60

Если у вас есть <form>, добавьте name к нему (предположим «Myform») и name на свой вход (предположим myInput). Вы должны быть в состоянии $watch этого путь:

scope.$watch('myForm.myInput.$valid', function(validity) {}) 

Если вы не имеете form, вы всегда можете посмотреть функцию. Таким образом:

scope.$watch(function() { return ctrl.$valid; }, function(validity){}); 

Вы можете прочитать больше о форме подхода here.

+1

Ваш второй подход сделал это для меня, спасибо! – Tiddo

7

Наша цель, в общем, состоит в том, чтобы сделать директивную работу независимо от какой-либо одной формы или ввода. Как мы можем позволить ему прочитать локальное свойство $valid без обязательной привязки его к одной конкретной форме & имя ввода?

Просто используйте require: 'ngModel' как одно из свойств вашей директивы. Это добавит локальный контроллер ngModel в качестве четвертого аргумента функции связи, и вы можете разместить $watch непосредственно на $valid, не связывая реализацию директивы с какой-либо конкретной формой или вводом.

require: 'ngModel', 
link: function postLink(scope, element, attrs, controller) { 
    scope.inputCtrl = controller; 
    scope.$watch('inputCtrl.$valid', handlerFunc) 
} 

Обработчик должен последовательно запускать изменения в $, действительные с этой структурой. См. this Fiddle, где вход подтвержден для шаблона почтового индекса U.S. или Zip + 4. Вы будете получать предупреждение каждый раз, когда будут изменены действительность.

РЕДАКТИРОВАТЬ 3/21/14: Это сообщение ранее было зависшим от моего заблуждения, фиксируя неправильную причину проблемы с реализацией. Моя вина. В приведенном выше примере удаляется эта фиксация. Кроме того, добавлена ​​скрипка, показывающая, что этот подход действительно работает и всегда делался, когда вы добавляете кавычки вокруг выражения watch.

+0

Вы уверены, что это работает? Потому что для меня кажется, что 'inputCtrl. $ Valid' будет оцениваться один раз (когда функция ссылки выполняется) и что результат передается в' scope. $ Watch'. Таким образом, это будет означать, что фактический вызов будет либо «scope. $ Watch (true, handlerFunc)», либо «scope». $ Watch (false, handlerFunc) », оба из которых не приводят к просмотру переменной. – Tiddo

+0

'inputCtrl. $ Valid' - это ссылка на свойство объекта, а не на примитивное значение. Он будет оцениваться как таковой каждый раз, когда срабатывает «$ watch». У меня есть работа над личными проектами, но в настоящее время нет хорошей публичной демонстрации. – XML

+1

AFAIK 'inputCtrl. $ Valid' Является примитивным. Это либо «истина», «ложь», либо «undefined», все из которых являются примитивами. Вы не можете создавать ссылки на свойства объектов, только для самих объектов в Javascript. См. Также этот JSFiddle: http://jsfiddle.net/9Mh92/2/. Как вы можете видеть, ваш код не вызывает обратный вызов, только с кавычками, которые он делает. Это опять же потому, что вы не можете создать ссылку на какой-либо примитив. Помещая кавычки вокруг 'inputCtrl. $ Valid', вы инструктируете угловое вычислять это выражение в текущей области и, таким образом, оно работает. – Tiddo

12

Если вы не имеете <form /> вы можете легко получить один:

В вашем определении директивы:

require: '^form' 

, а затем в функции связи, форма передается в качестве четвертого параметра:

link: function (scope, element, attr, ctrl) { 

Теперь вам не придется жестко прописать форму или поле ввода для выполнения $ часов:

scope.$watch(ctrl.$name + '.' + element.attr('name') + '.$valid', 
function (validity) {}); 
+0

Это было прекрасно. Хотя по какой-то причине мне пришлось использовать 'ctrl [0]. $ Name' - не знаю, почему мой элемент управления возвращал массив из 1 формы, хотя ... – DoubleA

+1

он вернет массив, если атрибуту 'require' передается массив (Я подозреваю, что это для вас) – pixelbits

Смежные вопросы