Angularjs: input ngChange se dispara mientras el valor está cambiando

ngChange se activa mientras el valor está cambiando (ngChange no es similar al clásico evento onChange). ¿Cómo puedo vincular el clásico evento onChange con angularjs, que solo se activará cuando se comprometan los contenidos?

Enlace actual:

 

Esta publicación muestra un ejemplo de una directiva que retrasa los cambios del modelo en una entrada hasta que se dispare el evento desenfoque .

Aquí hay un violín que muestra el ng-change trabajando con la nueva directiva ng-model-on-blur. Tenga en cuenta que esto es un ligero ajuste al violín original .

Si agrega la directiva a su código, cambiaría su enlace a esto:

  

Aquí está la directiva:

 // override the default input to update on blur angular.module('app', []).directive('ngModelOnblur', function() { return { restrict: 'A', require: 'ngModel', priority: 1, // needed for angular 1.2.x link: function(scope, elm, attr, ngModelCtrl) { if (attr.type === 'radio' || attr.type === 'checkbox') return; elm.unbind('input').unbind('keydown').unbind('change'); elm.bind('blur', function() { scope.$apply(function() { ngModelCtrl.$setViewValue(elm.val()); }); }); } }; }); 

Nota: como @wjin menciona en los comentarios a continuación, esta característica se admite directamente en Angular 1.3 (actualmente en beta) a través de ngModelOptions . Ver los documentos para más información.

Se trata de adiciones recientes a AngularJS, para servir como respuesta futura (también para otra pregunta ).

Versiones más nuevas angulares (ahora en 1.3 beta), AngularJS admite de forma nativa esta opción, utilizando ngModelOptions , como

 ng-model-options="{ updateOn: 'default blur', debounce: { default: 500, blur: 0 } }" 

Documentos de NgModelOptions

Ejemplo:

  

En caso de que alguien más busque soporte adicional para “presionar” las teclas, aquí hay una actualización del violín provisto por Gloppy

Código para el enlace de tecla:

 elm.bind("keydown keypress", function(event) { if (event.which === 13) { scope.$apply(function() { ngModelCtrl.$setViewValue(elm.val()); }); } }); 

Para cualquiera que esté luchando con IE8 (no le gusta la desvinculación (‘entrada’), encontré una forma de evitarlo.

Inyecte $ sniffer en su directiva y use:

 if($sniffer.hasEvent('input')){ elm.unbind('input'); } 

IE8 se calma si haces esto 🙂

De acuerdo con mi conocimiento, deberíamos usar ng-change con la opción de seleccionar y en caso de cuadro de texto deberíamos usar ng-blur.

¿No está usando $ scope. $ Watch para reflejar mejor los cambios de la variable de scope?

Anula la entrada predeterminada en el comportamiento de Cambio (llama a la función solo cuando se cambió el foco y el valor de pérdida de control)

NOTA: ngChange no es similar al clásico evento onChange que dispara el evento mientras el valor está cambiando Esta directiva almacena el valor del elemento cuando obtiene el foco
En desenfoques, comprueba si el nuevo valor ha cambiado y si es así, desencadena el evento

@param {String} – nombre de la función que se invocará cuando se active el “onChange”

@example

 angular.module('app', []).directive('myOnChange', function () { return { restrict: 'A', require: 'ngModel', scope: { myOnChange: '=' }, link: function (scope, elm, attr) { if (attr.type === 'radio' || attr.type === 'checkbox') { return; } // store value when get focus elm.bind('focus', function () { scope.value = elm.val(); }); // execute the event when loose focus and value was change elm.bind('blur', function () { var currentValue = elm.val(); if (scope.value !== currentValue) { if (scope.myOnChange) { scope.myOnChange(); } } }); } }; }); 

Tenía exactamente el mismo problema y esto funcionó para mí. Agrega ng-model-update y ng-keyup y listo. Aquí están los documentos