2016-07-12 2 views
2

У меня есть простая директива, называемая input-text, которая в основном обертывает входной контроль.Как обернуть ng-change в пользовательскую директиву?

Значение, присвоенное атрибуту input-text, передается ng-model и работает нормально. Теперь я также хочу передать функцию, которая вызывается при любом изменении модели, передав ее атрибуту input-change.

angular.module('test').directive('inputText', function() { 
    return { 
    restrict : 'A', 
    scope : { 
     inputText : '=' 
    }, 
    template : '<input ng-model="inputText" />', 
    link : function(scope, element, attr) { 
     var model = element.find('input').controller('ngModel'); 
     model.$viewChangeListeners.push(function() { 
     scope.$parent.$eval(attr.inputChange); 
     }); 
    } 
    } 

}); 

См. http://plnkr.co/edit/qC7FlxVNKH4SrAhLoJy4 для получения более подробной информации.

Функция, передаваемая директиве, вызывается каждый раз, когда я набираю элемент управления, но значение, которое я регистрирую в консоли, не является текущим $viewValue из элемента управления (но предыдущего).

Я также попробовал другой подход, передавая строку, заданную в input-change, чтобы ng-change на входной контроль следующим образом:

angular.module('test').directive('inputText', function() { 
    return { 
    restrict : 'A', 
    scope : { 
     inputText : '=', 
     inputChange : '&' 
    }, 
    template : '<input ng-model="inputText" ng-change="inputChange()" />', 
    } 

}); 

http://plnkr.co/edit/SutAFnCgo10QNmvBFsDs

Но выход такой же, как в приведенном выше примере.

Может кто-нибудь объяснить это поведение или сообщить, что здесь происходит не так?

ответ

0

Один из способов обойти это, чтобы явно выставить входное значение на его привязку input-change. Для этого вы можете использовать этот шаблон:

<input ng-model="inputText" ng-change="inputChange({value: inputText})" /> 

И затем использовать эту value переменные из внутреннего объема, а не test.model.name переменных из внешней области: input-change="test.callback(value)"

http://plnkr.co/edit/SNatIAkPIHFSMooMWWFS?p=preview


A второй вариант - следить за изменениями с помощью scope.$watch и запускать только свою функцию при срабатывании:

link: function(scope) { 
    scope.$watch('inputText', function(n) { 
    scope.inputChange(); 
    }); 
} 

http://plnkr.co/edit/Vrwe3SC3ejMG4aFIwBTU?p=preview

+0

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

+0

@ M.Redemske с опцией 1 ничего не мешает вам использовать другие переменные. Это jsut добавляет 'значение' как locals. Например, вы можете написать 'test.callback (model1, value, model2)' с model1 и model2, которые исходят из верхней области и 'value', которые предоставляются директивой. Что касается того, почему у вас возникла проблема, я также лично ее получил и никогда не знал, было ли это ошибкой в ​​самом угловом или что-то непонятное с ng-change. – floribon

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