在指令中使用`ng-if`时,与文本输入的数据绑定不起作用

时间:2016-06-23 15:38:28

标签: angularjs angularjs-directive

我创建了一个Angular指令(参见plunkr),如下所示:

JS:

angular.module('plunker', []);

angular.module('plunker').controller('MainCtrl', function($scope) {
  $scope.myInputs = {
    email: "test@test.org"
  }
  $scope.logToConsole = function() {
    console.log($scope.myInputs.email);
  }
});

angular.module('plunker').directive('myEmail', function(){
  return {
    restrict: 'E',
    scope: {
      myngmodel: '='
    },
    template: '<input type="email" ng-if="true" ng-model="myngmodel" />'
  };
});

它是从HTML中调用的:

<body ng-controller="MainCtrl">
    <my-email myngmodel="myInputs.email"></my-email>
    <input type="button" value="log to console!" ng-click="logToConsole()">
</body>

问题如下:

当我没有将ng-if="true"放在模板的textinput中,或者我使用ng-show时,绑定正常工作。

但是当ng-if="true"出现时,绑定不再起作用;当我编辑字段并单击按钮时,旧值始终写入控制台。

  • 这是一个错误还是按设计工作?
  • 问题是由于ng-model="myngmodel"没有遵循“点规则”吗?
  • 如果是这样,我怎么能重写指令,以便我能以同样的精神从外界传递数据模型条目?

1 个答案:

答案 0 :(得分:1)

ng-if创建了一个子范围 - 这就是它发生的原因。这里引用documentation

  

在ngIf中创建的范围使用原型继承从其父范围继承。这一点的一个重要含义是,如果在ngIf中使用ngModel绑定到父作用域中定义的javascript原语。在这种情况下,对子作用域内的变量所做的任何修改都将覆盖(隐藏)父作用域中的值。

因此,当您修改输入框中的值时 - 新值将写入继承指令的隔离范围的子范围:

<my-email myngmodel="myInputs.email" class="ng-isolate-scope">
    <input type="email" ng-if="true" ng-model="myngmodel" class="ng-scope">
</my-email>

MainCtrl范围var未更新,因为它绑定到指令的隔离范围var - 而不是其子范围。

解决方法是使用点表示法 - 确保ng-model读取和写入指令的父隔离范围:

指令的模板:

<input type="email" ng-if="true" ng-model="myngmodel.email" />

绑定到外部范围:

<my-email myngmodel="myInputs"></my-email>