javascript AngularJS - 模糊 + 改变?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20441779/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
AngularJS - Blur + Changed?
提问by Roger Johansson
What is the easiest way to combine ng-changed and ng-blur?
结合 ng-changed 和 ng-blur 的最简单方法是什么?
I've found this post: How to let ng-model not update immediately?
我找到了这篇文章:如何让 ng-model 不立即更新?
However, this does no longer work in angluar 1.2+ Is there any way to achieve the same behavior?
但是,这不再适用于angluar 1.2+ 有没有办法实现相同的行为?
I guess I have to store a copy of the old value myself and compare the new value to that on blur if I try to do the same, or is there any easier way ?
如果我尝试这样做,我想我必须自己存储旧值的副本并将新值与模糊中的值进行比较,或者有没有更简单的方法?
采纳答案by Roger Johansson
This does what I want. It stores the value on focus, and compares it to the new value on blur, if changed, it triggers the expression in the attribute.
这就是我想要的。它存储焦点上的值,并将其与模糊上的新值进行比较,如果更改,则触发属性中的表达式。
app.directive('changeOnBlur', function() {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, elm, attrs, ngModelCtrl) {
if (attrs.type === 'radio' || attrs.type === 'checkbox')
return;
var expressionToCall = attrs.changeOnBlur;
var oldValue = null;
elm.bind('focus',function() {
scope.$apply(function() {
oldValue = elm.val();
console.log(oldValue);
});
})
elm.bind('blur', function() {
scope.$apply(function() {
var newValue = elm.val();
console.log(newValue);
if (newValue !== oldValue){
scope.$eval(expressionToCall);
}
//alert('changed ' + oldValue);
});
});
}
};
});
usage:
用法:
<input ng-model="foo" change-on-blur="someFunc()" />
回答by Niels Steenbeek
Use ng-model options.
Like this, ng-changewill only trigger when the input is blurred.
使用ng-model options. 像这样,ng-change只会在输入模糊时触发。
<input type="text"
ng-model="a.b"
ng-model-options="{updateOn: 'blur'}"
ng-change="onchange()"/>
回答by Michael
How about this solution. Works for me:
这个解决方案怎么样。对我有用:
<input ng-init="oldValue = value" ng-model="value"
ng-blur="oldValue != value && callYourFunc(foo)">
回答by Yogesh Manware
I am using AngularJs 1.2.x and stumbled upon the ng-change issue of firing on each change. ng-blur can be used but it fires even though there is no change in the value. So both cannot be used efficiently.
我正在使用 AngularJs 1.2.x 并偶然发现了每次更改时触发的 ng-change 问题。可以使用 ng-blur 但即使值没有变化它也会触发。所以两者都不能有效地使用。
With Angularjs 1.3.x, things are easier using ng-model-optionslike below
使用 Angularjs 1.3.x,使用ng-model-options下面的方法更容易
to invoke change function "onBlur"
调用更改功能“onBlur”
ng-change="ctrl.onchange()" ng-model-options="{updateOn: 'blur'}"
ng-change="ctrl.onchange()" ng-model-options="{updateOn: 'blur'}"
And
和
to delay invocation of change function by 500ms
将更改功能的调用延迟 500 毫秒
ng-change="ctrl.onchange()" ng-model-options='{ debounce: 500 }'"
ng-change="ctrl.onchange()" ng-model-options='{ debounce: 500 }'"
Now coming to back to the question of getting such things with AngularJs 1.2.x
现在回到用 AngularJs 1.2.x 获得这些东西的问题
to invoke change function "onBlur"
调用更改功能“onBlur”
html
html
<input type="text" ng-model="ctrl.a.c" sd-change-on-blur="ctrl.onchange()" />or
<input type="text" ng-model="ctrl.a.c" sd-change-on-blur="ctrl.onchange()" />或者
<input type="text" ng-model="ctrl.a.c" sd-change-on-blur="ctrl.onchange(ctrl.a.c)" />
<input type="text" ng-model="ctrl.a.c" sd-change-on-blur="ctrl.onchange(ctrl.a.c)" />
JS
JS
app.directive('sdChangeOnBlur', function() {
return {
restrict: 'A',
scope: {
sdChangeOnBlur: '&'
},
link: function(scope, elm, attrs) {
if (attrs.type === 'radio' || attrs.type === 'checkbox')
return;
var parameters = getParameters(attrs.sdChangeOnBlur);
var oldValue = null;
elm.bind('focus', function() {
scope.$apply(function() {
oldValue = elm.val();
});
})
elm.bind('blur', function() {
scope.$apply(function() {
if (elm.val() != oldValue) {
var params = {};
if (parameters && parameters.length > 0) {
for (var n = 0; n < parameters.length; n++) {
params[parameters[n]] = scope.$parent.$eval(parameters[n]);
}
} else {
params = null;
}
if (params == null) {
scope.sdChangeOnBlur();
} else {
scope.sdChangeOnBlur(params)
}
}
});
});
}
};
});
function getParameters(functionStr) {
var paramStr = functionStr.slice(functionStr.indexOf('(') + 1, functionStr.indexOf(')'));
var params;
if (paramStr) {
params = paramStr.split(",");
}
var paramsT = [];
for (var n = 0; params && n < params.length; n++) {
paramsT.push(params[n].trim());
}
return paramsT;
}
to delay invocation of change function by 500ms
将更改功能的调用延迟 500 毫秒
html
html
<input type="text" ng-model="name" sd-change="onChange(name)" sd-change-delay="300"/>
<input type="text" ng-model="name" sd-change="onChange(name)" sd-change-delay="300"/>
OR
或者
<input type="text" ng-model="name" sd-change="onChange()" sd-change-delay="300"/>
<input type="text" ng-model="name" sd-change="onChange()" sd-change-delay="300"/>
JS
JS
app.directive('sdChange', ['$timeout',
function($timeout) {
return {
restrict: 'A',
scope: {
sdChange: '&',
sdChangeDelay: '@' //optional
},
link: function(scope, elm, attr) {
if (attr.type === 'radio' || attr.type === 'checkbox') {
return;
}
if (!scope.sdChangeDelay) {
scope.sdChangeDelay = 500; //defauld delay
}
var parameters = getParameters(attr.sdChange);
var delayTimer;
elm.bind('keydown keypress', function() {
if (delayTimer !== null) {
$timeout.cancel(delayTimer);
}
delayTimer = $timeout(function() {
var params = {};
if (parameters && parameters.length > 0) {
for (var n = 0; n < parameters.length; n++) {
params[parameters[n]] = scope.$parent.$eval(parameters[n]);
}
} else {
params = null;
}
if (params == null) {
scope.sdChange();
} else {
scope.sdChange(params)
}
delayTimer = null;
}, scope.sdChangeDelay);
scope.$on(
"$destroy",
function(event) {
$timeout.cancel(delayTimer);
console.log("Destroyed");
}
);
});
}
};
}
]);
function getParameters(functionStr) {
var paramStr = functionStr.slice(functionStr.indexOf('(') + 1, functionStr.indexOf(')'));
var params;
if (paramStr) {
params = paramStr.split(",");
}
var paramsT = [];
for (var n = 0; params && n < params.length; n++) {
paramsT.push(params[n].trim());
}
return paramsT;
}
plnkrs for both approaches are
两种方法的 plnkrs 是
http://plnkr.co/edit/r5t0KwMtNeOhgnaidKhS?p=preview
http://plnkr.co/edit/r5t0KwMtNeOhgnaidKhS?p=preview
回答by Chris Montgomery
how about this plunkr?
using angular's built in ng-blur, update your "persisted value" on blur
使用 angular 的内置ng-blur,更新模糊上的“持久值”
<input type="text" ng-model="boxValue" ng-blur="doneEditing(boxValue)">
when saving, verify the value is different
保存时,验证值不同
$scope.doneEditing = function(v) {
if (v !== $scope.persistedValue) // only save when value is different
$scope.persistedValue=v;
}
There is no special option on ng-blurfor pre-checking equality that I'm aware of. A simple ifseems to do the trick
ng-blur我所知道的预检查相等性没有特殊选项。一个简单的if似乎可以解决问题
回答by manikanta
Newer versions of AngularJS (now in 1.3 beta) supports this natively. See my answer here
回答by Kmeixner
The solution that worked for me was as follows:
对我有用的解决方案如下:
<input id="fieldId" type="text"
ng-model="form.fields.thisField"
ng-model-options="{ updateOn: 'blur' }"
ng-change="form.save()" />
I found this solution here
我在这里找到了这个解决方案
That page says it requires AngularJS version 1.3.0+ . I tested it with AngularJS version 1.5.11 and it works in that version for me.
该页面说它需要 AngularJS 版本 1.3.0+ 。我使用 AngularJS 版本 1.5.11 对其进行了测试,它在该版本中对我有效。
回答by Vaibhav Lokhande
In app.html
在 app.html
<input type="text" name="name" ng-model="$ctrl.user.name" ng-blur="$ctrl.saveChanges()" ng-change="$ctrl.onFieldChange()"/>
in app.ts
在 app.ts
public onFieldChange() {
this.isValuesModified = true;
}
//save changes on blur event
public saveChanges() {
//check if value is modified
if(this.isValuesModified){
//Do your stuff here
}
}

