Angular指令:在隔离范围内使用ng-model

时间:2014-06-17 14:00:36

标签: angularjs angularjs-directive angularjs-scope

我无法弄清楚如何定义两者的自定义指令:

  1. 使用隔离范围和
  2. 在其模板中的新范围内使用ng-model指令。
  3. 以下是一个例子:

    HTML:

    <body ng-app="app">
      <div ng-controller="ctrl">
        <dir model="foo.bar"></dir>
        Outside directive: {{foo.bar}}
      </div>
    </body>
    

    JS:

    var app = angular.module('app',[])
      .controller('ctrl', function($scope){
        $scope.foo = { bar: 'baz' };
      })
      .directive('dir', function(){
        return {
          restrict: 'E',
          scope: {
            model: '='
          },
          template: '<div ng-if="true"><input type="text" ng-model="model" /><br/></div>'
        }
      });
    

    此处所需的行为是输入的值通过指令的(隔离)范围foo.bar属性绑定到外部作用域的model属性。这种情况不会发生,因为模板封闭div上的ng-if指令会创建一个新的范围,因此范围的model会更新,而不是指令的范围。 通常你通过确保表达式中有一个点来解决这些ng模型问题,但我在这里看不到任何方法。我想知道我是否可以在我的指令中使用这样的东西:

    {
      restrict: 'E',
      scope: {
        model: {
          value: '=model'
        }
      },
      template: '<div ng-if="true"><input type="text" ng-model="model.value" /><br/></div>'
    }
    

    但这不起作用......

    Plunker

2 个答案:

答案 0 :(得分:9)

您是对的 - ng-if创建一个子范围,在输入文本字段中输入文本时会导致问题。它在子作用域中创建一个名为“model”的shadow属性,它是具有相同名称的父作用域变量的副本 - 有效地打破了双向模型绑定。

对此的修复很简单。在模板中,指定$ parent前缀:

  template: '<div ng-if="true">
                   <input type="text" ng-model="$parent.model" /><br/>
             </div>'

这确保它将从$ parent范围中解析'model',您已经为隔离范围内的双向模型绑定设置了该范围。

最后,'。'在ng-model中节省了一天。我发现考虑点的任何内容作为Angular通过范围继承解析属性的一种方法是有用的。如果没有点,当我们分配范围变量时,解析属性只会成为问题(否则,查找很好,包括只读{{model}}绑定表达式)。

答案 1 :(得分:0)

ng-if创建了一个额外的原型继承范围,因此ng-model="model"绑定到新范围的继承属性,而不绑定到指令范围的双向绑定属性。

将其更改为ng-show,它将work

您可以使用我编写的a small Firebug extension来检查角度范围。