【问题标题】:Calling $setViewValue in a directive doesn't fire $watch in the controller在指令中调用 $setViewValue 不会在控制器中触发 $watch
【发布时间】:2014-08-08 10:32:53
【问题描述】:

我正在使用这样的 ngModelController 指令

  var directive = {
    link: link,
    restrict: 'E',
    require: '?ngModel'
  }

我的链接函数做这样的事情(我省略了长指令的东西)

function link(scope, element, attrs, ctrl) {

  scope.updateModel = function(){
    var newModel = {};
    newModel.aValue = 'foo';
    ctrl.$setViewValue(newModel);
  }

}

我在控制器中使用指令

查看:已正确更新

<my-directive ng-model="aModel">
  {{aModel.aValue}} // This is changed correctly when I update the value in the directive
</my-directive>

控制器:这是我遇到问题的地方

$scope.aModel = {};
$scope.aModel.aValue = 'bar';

$scope.$watch('aModel', function(newValue, oldValue){
    console.log('aModel changed'); // This is never fired
});

$scope.$watch('aModel.aValue', function(newValue, oldValue){
    console.log('aModel changed'); // This is neither fired
});

$setViewValue 的文档说

"请注意,调用此函数不会触发 $digest。"

所以我尝试使用$render$digest$apply 手动触发它,但每次都会遇到麻烦,因为控制台说$digest is already in progress
那么这有什么问题呢?

更新

我刚刚意识到一些非常有趣的事情。
添加$timeout 来检查控制器中的值,我意识到它实际上并没有改变,这可能是 $watch 函数没有被调用的原因。
但是由于视图已更新,我真的不明白这一点。

情况是这样的:

控制器

$timeout(function(){
  console.log('Check aModel value in the controller');
  console.log($scope.aModel.aValue); // This is always 'bar' even if the view display 'foo'
},10000);

更新 2

我想我发现了问题:ngModel 不能是一个对象,但它必须是一个值。
我将这个问题保持开放,看看是否有人提出了不同的解决方案,但我想这就是重点。

更新 3
我错了,您可以将 ngModel 更新为对象,但无法触发 $watch 方法。
我创建a plunker to show the problem
我设置了很大的超时时间以避免任何 $digest 正在进行的问题。
任何提示将不胜感激。

【问题讨论】:

    标签: javascript angularjs angularjs-directive digest angular-ngmodel


    【解决方案1】:

    $watch函数中添加第三个参数true

    【讨论】:

    • 感谢您的建议,但这并不能解决问题。
    【解决方案2】:

    使用不带时间参数的 $timeout 来调用 $apply 并触发摘要循环。这将导致它在几分之一秒后执行,并且不会在摘要循环错误中进入摘要循环。显然,您所做的不是“角度感知”,因此您需要使用 $apply 触发摘要循环,但您在摘要循环中,因此您需要使用上面提到的“hack”。

    【讨论】:

      猜你喜欢
      • 2016-03-13
      • 1970-01-01
      • 2016-03-11
      • 2014-01-04
      • 2015-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-05
      相关资源
      最近更新 更多