AngularJS:input [text] ngChange在值更改时触发


92

更改值时会触发ngChange(ngChange与经典的onChange事件不相似)。如何将经典的onChange事件与angularjs绑定在一起,只有在提交内容时才会触发?

当前绑定:

<input type="text" ng-model="name" ng-change="update()" />

只是寻找类似的东西,我想到您可能还想考虑仅在该字段有效时进行更新。这样,用户就很难将输入格式转换为有效格式(或者您可以通过提示和过滤器帮助他们),然后在他们输入正确的内容时向他们奖励更新!
史蒂夫·布莱克

一个更灵活的解决方案,允许指定事件的使用(不只是模糊)等性质,应该建立在对角很快:github.com/angular/angular.js/pull/2129
wired_in

Answers:


96

这篇文章显示了一个指令示例,该指令将模型对输入的更改延迟到模糊事件触发之前。

是一个小提琴,显示了ng-change与新的ng-model-on-blur指令一起使用。请注意,这是对原始提琴的略微调整。

如果将指令添加到代码中,则将绑定更改为:

<input type="text" ng-model="name" ng-model-onblur ng-change="update()" />

这是指令:

// 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());
                });         
            });
        }
    };
});

注意:正如@wjin在下面的注释中提到的,此功能在Angular 1.3(当前为beta)中通过受到直接支持ngModelOptions。有关更多信息,请参阅文档


1
注意,elm.unbind('input')在Internet Explorer 8中引发“ TypeError”,因此将完全不执行其他unbind语句。我通过将elm.unbind('input')移到另一行并用try / catch块将其包围来解决它。
Rob Juurlink

1
Angular 1.2有一条ng-blur指令:docs.angularjs.org/api/ng.directive
JJ Zabkar 2013年

5
我使这段代码起作用,但是我必须设置指令的优先级(即,优先级:100)。我正在使用Angular 1.2.10。我的猜测是ngModelOnblur指令在ngModel指令之前运行,因此尚无任何绑定。另外,此页面看起来似乎将来可能会有一个内置的解决方案:github.com/angular/angular.js/pull/1783
Alan West

4
注意:至少在angular 1.3中,默认实现通过此功能支持此功能,ng-model-options="{ updateOn: 'default blur' }"请参见文档
wjin 2014年

2
@RobJuurlink(或尝试绑定或取消绑定到“输入”时遇到IE8“ TypeError”的任何人)-查看Angular的源代码,您会发现它们用于$sniffer确定浏览器是否支持“输入”,如果不支持,他们回到“ keydown”。如果您将上述指令更新为仅在$sniffer.hasEvent('input')返回true 时才取消绑定“输入” ,那么您可以避免该错误并仍在IE8中工作
bvaughn 2014年

32

这是关于AngularJS的最新添加,以作为将来的答案(也适用于另一个问题)。

Angular较新的版本(现在处于1.3 beta版),AngularJS原生支持此选项,使用ngModelOptions,例如

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

NgModelOptions文档

例:

<input type="text" name="username"
       ng-model="user.name"
       ng-model-options="{updateOn: 'default blur', debounce: {default: 500, blur: 0} }" />

它在1.3 beta 5中无法正常运行,但在当前的主版本2602中已修复
manikanta 2014年

这就是为什么它仍处于beta版本,而不能在“现实世界”应用程序(例如我现在正在构建的应用程序)中使用的原因。
reaper_unique 2014年

这是Angular 1.2.x的ng-model-options类似模块github.com/fergaldoyle/modelOptions
Fergal

8

如果其他任何人正在寻找其他“输入”按键支持,这里是Gloppy提供的小提琴的更新。

按键绑定代码:

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

5

对于任何使用IE8(不喜欢unbind('input')的人),我找到了解决之道。

将$ sniffer注入您的指令并使用:

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

IE8冷静下来,如果您这样做:)


或仅使用try / catch
–wired_in

4

据我所知,我们应该在选择选项中使用ng-change,在文本框的情况下,我们应该使用ng-blur。


现在,这是正确的答案,而当问这个问题时,它显然不存在。
2015年

非常感谢...这应该是答案
Renjith


0

覆盖默认的输入onChange行为(仅当控件损失焦点和值发生更改时才调用该函数)

注意:ngChange与经典的onChange事件不同,它会在值更改时触发事件。此伪指令在获得焦点时会存储元素的值。On会
模糊检查它是否更改了新值,如果触发则触发事件

@param {String}-应该触发“ onChange”时要调用的函数名称

@example <输入my-on-change =“ myFunc” ng-model =“ model”>

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();
                    }
                }
            });
        }
    };
});

0

我遇到了完全相同的问题,这对我有用。添加ng-model-updateng-keyup您就可以开始了!这是文档

 <input type="text" name="userName"
         ng-model="user.name"
         ng-change="update()"
         ng-model-options="{ updateOn: 'blur' }"
         ng-keyup="cancel($event)" />
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.