为什么我的嵌套指令在调用$ setViewValue()后立即与其ngModel断开连接?

时间:2014-10-29 13:54:39

标签: angularjs angularjs-directive angularjs-scope angular-ngmodel

Plunker here.

我有一个嵌套在另一个指令(“parent”)中的指令(“child”)。 require s ngModel和ngModelCtrl.$modelValue在其模板中显示并保持最新状态。也就是说,直到我调用ngModelCtrl。$ setViewValue()。

所以这里是HTML初始化指令:

<div parent>
  <div child ng-model="content">Some</div>
</div>

以下是指令:

angular.module('form-example2', [])
  .controller('MainCtrl', function($scope){
  $scope.content = 'Hi';
})
.directive('parent', function() {
  return {
    transclude: true,
    template: '<div ng-transclude></div>',
    controller: function(){
    },
    scope: {}
  };
})
.directive('child', function() {
  return {
    require: ['ngModel', '^parent'],
    transclude: true,
    template: '<div>Model: {{model.$modelValue}} (<a style="text-decoration: underline; cursor: pointer;" ng-click="alter()">Alter</a>)<br />Contents: <div style="background: grey" ng-transclude></div></div>',
    scope: {},
    link: function(scope, elm, attrs, ctrl) {
      var ngModelCtrl = ctrl[0];
      var parentCtrl = ctrl[1];

      scope.model = ngModelCtrl;

      // view -> model
      scope.alter = function(){
        ngModelCtrl.$setViewValue('Hi2');
      }

      // model -> view

      // load init value from DOM
    }
  };
});

当模型(即content)发生变化时,可以在子指令内看到此变化。当您单击“更改”链接(触发$ setViewValue()的调用)时,模型的值应变为“Hi2”。这正确显示在child指令中,但不在指令外的模型中。此外,当我现在更新指令外的模型时,它不再在指令内更新。

怎么回事?

1 个答案:

答案 0 :(得分:0)

指令结果很好;唯一的问题是传递的模型应该是一个对象属性。因此,如果对调用代码(Plunker)进行了以下修改,则指令有效:

在控制器中,而不是$scope.content = 'Hi';

$scope.content = {
  value: 'Hi'
};

在模板中,将所有对content的引用替换为content.value

<input ng-model="content.value" type="text" />
<div parent>
  <div child ng-model="content.value">Some</div>
  </div>
<pre>model = {{content.value}}</pre>

大致这个原因是,当Angular将对模型的引用传递给父指令的transcluded范围(即子指令所在的范围)时,这只是引用对象属性时的引用 - 否则它是一个副本,Angular无法监视变化。

@ Josep的回答非常有帮助,即使它没有提供实际的解决方案,如果你正在阅读它并且它很有用,那就投票吧:)