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-change
will 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-options
like 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-blur
for pre-checking equality that I'm aware of. A simple if
seems 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
}
}