ngIf中的绑定元素不会更新绑定

时间:2014-02-02 15:13:43

标签: javascript angularjs angularjs-directive

我写了一个angularjs指令。 在这个指令的模板中,我添加了一个ngIf指令,在其中我显示了一个绑定到我的指令范围的输入。

<div ng-if="bool"><input ng-model="foo"></div>

我注意到,经过大量的试验和错误后,ngIf指令导致模型在输入文本更改时不会更新。如果我将它改为ngShow,一切都按预期工作。

我正在寻找这种差异的解释

I have created a jsfiddle here

3 个答案:

答案 0 :(得分:29)

这是因为ngIf创建了一个新的子范围,所以如果你想绑定到与其他输入相同的范围,我们可以用$ parent向下一级。检查here以了解有关范围继承的更多信息

  angular.module('testApp', [])
  .directive('testDir', function () {
    return {
      restrict: 'A',
      template: '<input ng-model="foo"><input ng-model="foo">' +
         '<div ng-if="bool"><input ng-model="$parent.foo"></div>',
      link: function (scope, elem, attrs) {
        scope.foo = "bar";
        scope.bool = true;       
      }
    }
  });

看看新的jsfiddle

答案 1 :(得分:20)

这是因为你在范围上使用了一个原语。

ngIf创建一个新的子范围,它会遮蔽父范围的值。

改为使用点符号:

<div ng-if="bool"><input ng-model="data.foo"></div>

来自Understanding Scopes wiki:

  

范围继承通常很简单,你甚至不需要知道它正在发生......直到你尝试双向数据绑定(即表单元素,ng-model)到一个原语(例如,数字) ,string,boolean)在子范围内从父范围定义。

     

它不像大多数人预期的那样有效。会发生的是子作用域获取自己的属性,该属性隐藏/隐藏同名的父属性。这不是AngularJS正在做的事情 - 这就是JavaScript原型继承的工作原理。

     

新的AngularJS开发人员通常没有意识到 ng-repeat,ng-switch,ng-view和ng-include都创建了新的子范围,因此当涉及这些指令时,问题经常会出现。

     

通过遵循始终have a '.' in your ng-models的“最佳实践”,可以轻松避免使用原语这个问题。

答案 2 :(得分:2)

将foo定义为具有属性的对象。这一切都与javascript原型继承有关。查看修改后的jsfiddle

 angular.module('testApp', [])
  .controller('MyController',function($scope){
      $scope.foo = {bool: true};
  })
  .directive('testDir', function () {
    return {
      restrict: 'A',
      template: '<input ng-model="foo.x"><input ng-model="foo.x"><div ng-if="foo.bool"><br/>changing me does not update the other inputs because i am in an ngIf if in ngShow all works just fine<input ng-model="foo.x"></div>',
      link: function (scope, elem, attrs) {
        scope.foo.x = "bar";
        scope.foo.bool = true;       
      }
    }
  });

有关详细信息,请参阅此video