Как создать on-change директиву для AngularJS?
Обычно ng-модель обновляет связанную модель каждый раз, когда пользователь нажимает клавишу:
<input type="text" ng-model="entity.value" />
Это отлично работает почти в каждом случае.
Но мне нужно, чтобы он обновлялся, когда событие onchange происходит вместо события onkeyup/onkeydown.
В более старых версиях angular появилась директива ng-model-instant, которая работала так же, как и ng-model (сейчас, по крайней мере, для пользователя - я ничего не знаю об их реализации).
Поэтому в старой версии, если я только что дал ng-model, она обновляла модель onchange, и когда я указал ng-model-instant, она обновляла модель onkeypup.
Теперь мне нужна ng-модель для использования в событии "change" элемента. Я не хочу, чтобы это было мгновенно. Какой самый простой способ сделать это?
ИЗМЕНИТЬ
Вход еще должен отражать любые другие изменения в модели - если модель будет обновлена в другом месте, значение ввода должно отражать это изменение.
Мне нужно, чтобы директива ng-model работала так же, как она работала в более старых версиях angularjs.
Вот объяснение того, что я пытаюсь сделать:
http://jsfiddle.net/selbh/EPNRd/
Ответы
Ответ 1
Здесь я создал onChange директиву для вас. Демо: http://jsfiddle.net/sunnycpp/TZnj2/52/
app.directive('onChange', function() {
return {
restrict: 'A',
scope:{'onChange':'=' },
link: function(scope, elm, attrs) {
scope.$watch('onChange', function(nVal) { elm.val(nVal); });
elm.bind('blur', function() {
var currentValue = elm.val();
if( scope.onChange !== currentValue ) {
scope.$apply(function() {
scope.onChange = currentValue;
});
}
});
}
};
});
Ответ 2
См. также: директива AngularJS ngChange.
При применении к <input> изменения происходят после каждого нажатия клавиши не на событие размытия.
http://docs.angularjs.org/api/ng.directive:ngChange
Ответ 3
Angularjs: input [текст] ngChange срабатывает при изменении значения: этот ответ обеспечивает гораздо лучшее решение, позволяющее настраиваемой директиве работать с ngModel
, поэтому вы все равно можете использовать все другие директивы, которые идут вместе с ngModel
.
Кроме того, очень скорое решение, которое позволяет указать, какое событие использовать (а не просто размытие) и другие свойства, должно быть скоро установлено в angular: https://github.com/angular/angular.js/pull/2129
Ответ 4
Я не уверен, есть ли лучший способ сделать это, но вы можете достичь этого, используя настраиваемую директиву (в любом событии jquery, которое вы хотите)
<input type="text" ng-model="foo" custom-event="bar" />
<p> {{ bar }} </p>
// create the custom directive
app.directive('customEvent', function() {
return function(scope, element, attrs) {
var dest = attrs.customEvent;
$(element[0]).on('any-jquery-event', function(e) {
e.preventDefault();
// on the event, copy the contents of model
// to the destination variable
scope[dest] = scope.foo;
if (!scope.$$phase)
scope.$apply();
});
}
});