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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 03:04:18  来源:igfitidea点击:

AngularJS Directive Two-Way Data Binding Not Working When Observing Boolean

javascriptangularjsangularjs-directive

提问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