【问题标题】:Why does my nested directive disconnect from its ngModel as soon as $setViewValue() is called?为什么我的嵌套指令在调用 $setViewValue() 后立即与它的 ngModel 断开连接?
【发布时间】:2014-12-25 06:23:12
【问题描述】:

Plunker here.

我有一个指令(“子”)嵌套在另一个指令(“父”)中。 requires 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)发生变化时,可以在子指令中看到这种变化。当您单击“Alter”链接(触发 $setViewValue() 调用)时,模型的值应变为“Hi2”。这在 child 指令内正确显示,但不在指令外的模型中显示。此外,当我现在在指令外更新模型时,它不再在指令内更新。

怎么会?

【问题讨论】:

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


    【解决方案1】:

    指令结果很好;唯一的问题是传递的模型应该是一个对象属性。因此,如果对调用代码 (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 将对模型的引用传递给父指令(即子指令所在的那个)的嵌入范围时,这只是在引用对象属性时的引用- 否则它是一个副本,Angular 无法监视更改。

    @Josep 的回答帮助很大,即使它没有提供实际的解决方案,如果您正在阅读这篇文章并且它很有用,请给它投票:)

    【讨论】:

    • 感谢您的更新。因此,如果该陈述是错误的,那么按上述方式更改它可以解决问题的原因是什么?此外,当 ngModel 绑定到“当前”范围时,在这种情况下,它不是控制器范围的子级吗?由于父指令的嵌入使得被嵌入内容的范围成为父指令范围的兄弟。这应该意味着content 仍然指的是控制器的型号,对吧?
    • 我绝对想了解,这就是我问所有这些问题的原因:) 所以你所说的scope.model = ngModelCtrl; 是有道理的。但是,当我不这样做时(确实更清洁),它仍然不适用于原始模型:plnkr.co/edit/oAJ7cvWSj1PmHbA7VL36?p=preview 你知道为什么会这样吗?另外,您是否删除了答案? :(
    猜你喜欢
    • 2016-03-28
    • 1970-01-01
    • 2020-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-16
    • 2015-06-21
    相关资源
    最近更新 更多