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

Dun*_*can 10 angularjs angularjs-directive angularjs-scope

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

  1. 使用隔离范围,和
  2. 在其模板中的新范围内使用ng-model指令.

这是一个例子:

HTML:

<body ng-app="app">
  <div ng-controller="ctrl">
    <dir model="foo.bar"></dir>
    Outside directive: {{foo.bar}}
  </div>
</body>
Run Code Online (Sandbox Code Playgroud)

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>'
    }
  });
Run Code Online (Sandbox Code Playgroud)

这里所需的行为是输入的值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>'
}
Run Code Online (Sandbox Code Playgroud)

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

Plunker

pix*_*its 9

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

解决这个问题很简单.在模板中,指定$ parent前缀:

  template: '<div ng-if="true">
                   <input type="text" ng-model="$parent.model" /><br/>
             </div>'
Run Code Online (Sandbox Code Playgroud)

这可以确保它将从$ parent范围中解析"模型",您已经设置了通过隔离范围进行双向模型绑定的$ parent范围.

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