Javascript 观察布尔值时,AngularJS 指令双向数据绑定不起作用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29265310/
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 Directive Two-Way Data Binding Not Working When Observing Boolean
提问by Evil Closet Monkey
I have a two-way data binding that is not altering the value of the variable sent to the directive.
我有一个双向数据绑定,它不会改变发送到指令的变量的值。
My directive watches for a trigger and gives focus to the associates element (based on code found here at SO):
我的指令监视触发器并将焦点放在 associates 元素上(基于在 SO 上找到的代码):
app.directive('focusMe', function ($timeout) {
return {
scope: {
trigger: '=focusMe'
},
link: function (scope, element, attrs) {
scope.$watch('trigger', function(value) {
console.log("directive value: " + value);
console.log("directive start: " + scope.trigger);
if (value === true) {
$timeout(function () {
element[0].focus();
scope.trigger = false;
console.log("directive end: " + scope.trigger);
});
}
});
}
}
});
In the HTML I call it as follows:
在 HTML 中,我这样称呼它:
<input type="text" ng-model="item.value" focus-me="focusInput" />
When I trigger it for the first time, it works -- because the focusInputvariable switches its value. But focusInputin the controllers scope (outside the directive) does not switch back to falsewhen the directive completes.
当我第一次触发它时,它起作用了——因为focusInput变量会切换它的值。但是focusInput在控制器范围内(指令之外)不会切换回false指令完成时。
This switch back to falseshould happen when I call scope.trigger = false, assuming I understand what should be happening.
假设我明白应该发生什么,false当我调用 时scope.trigger = false,这个切换回应该发生。
What is missing that would cause the two-way binding to not push the value back to the variable passed into the directive?
缺少什么会导致双向绑定不会将值推回传递给指令的变量?
UPDATE 01:
更新 01:
For posting the question I removed a small bit of code. The HTML actually looks like this:
为了发布这个问题,我删除了一小段代码。HTML实际上是这样的:
<input type="text" ng-model="item.value" focus-me="focusInput" ng-if="item.condition != 'matches' && item.condition != 'does not match'" />
If the inputfields hides and then is re-shown (based on the ng-if) the directive will properly give focus the first time focusInputchanges. It will stop working again after that... unless the hide/show process is repeated.
如果input字段隐藏然后重新显示(基于ng-if),则指令将在第一次focusInput更改时正确提供焦点。之后它将再次停止工作......除非重复隐藏/显示过程。
回答by Omri Aharon
The problem you are experiencing is a common problem when dealing with primitive values (boolean, int, etc..) within scopes.
在处理范围内的原始值(布尔值、整数等)时,您遇到的问题是一个常见问题。
I strongly suggest reading Understanding Scopesarticle. (short answer: primitives are changed in the directive's isolated scope, and are not seeked up the chain for the parent scope, i.e., your controller scope).
我强烈建议阅读理解范围文章。(简短的回答:原语在指令的隔离范围内发生变化,并且不会在父范围的链中寻找,即您的控制器范围)。
As to how to solve your situation, I suggest to use dot notation and store your primitive inside an object, and bind this object to your directive:
至于如何解决您的情况,我建议使用点表示法并将您的原语存储在一个对象中,并将此对象绑定到您的指令:
scope: {
triggerObj: '=focusMe'
},
And make sure your trigger references in the directive are now scope.triggerObj.trigger.
并确保指令中的触发器引用现在是scope.triggerObj.trigger.
And in your controller have:
在你的控制器中有:
$scope.triggerObj = {};
$scope.triggerObj.trigger = true; //or false, what have you
Having an object will make sure the two way binding will work. And read the article above when you have time :)
拥有一个对象将确保双向绑定将起作用。当你有时间的时候阅读上面的文章:)
回答by Elad
Directive create a scope. when you pass parameter to scope, object passed by reference and boolean (and number, string...) passed by value.
指令创建范围。当您将参数传递给作用域时,对象通过引用传递,布尔值(和数字、字符串...)通过值传递。
For example:
例如:
function changeToFalse(bool) {
bool= false;
console.log(bool); // false
}
function changeObjToFalse(obj) {
obj.bool= false;
console.log(obj.bool); // false
}
var obj = {bool : true};
changeToFalse(obj.bool);
console.log(obj.bool); // true
changeObjToFalse(obj);
console.log(obj.bool); // false
See also same question - two way binding not working with ng-repeat.
另请参阅相同的问题 -双向绑定不适用于 ng-repeat。

