Как создать 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();
        });
    }
});