我有这样的结构(简化了很多):

<div ng-controller="MainCtrl">
  <div>Views and other stuff</div>
    <div ng-controller="MyCtrl">
      <div ng-repeat="item in $root.items track by $index">
        {{item.id}}
      </div>
    <div>
        Total value: {{totVal}}
    </div>
  </div>
</div>


在我的主控制器中,我定义了$ rootScope.items = [{{id:1,..},{id:2,..},{id:3,..},..],在我的其他控制器中,我定义了已经定义了$ scope.totVal = 0和一个items数组的观察者,当items数组更改时,该数组更新了totVal;

.controller('MainCtrl', ['$rootScope', '$scope', function($rootScope, $scope) {
    // Are actually fetched from a service
    $rootScope.items = [
        {id: 1,..},
        {id: 2,..},
        ..
    ];
}])

.controller('MyCtrl', ['$rootScope', '$scope', function($rootScope, $scope) {
    $rootScope.updateTotVal = function() {
        var totVal = 0;
        // calculations are done here
        // Is correct here when I console log after all calculations are complete
        console.log(totVal);
        $scope.totVal = totVal;
    }

    $scope.totVal = 0;

    $rootScope.$watch('items', function() {
        $rootScope.updateTotVal();
    }, true);
}]);


我的问题是该totVal不会在视图中更新。当我使用控制台日志记录值时,它会在控制台中正确显示,但是如果我将totVal div滚动出视图并再次返回,它只会在视图中更新。似乎是Chrome中的AngularJS错误,但是当我使用Google时找不到任何类似的情况。它在FireFox中工作正常。

如果在ng-repeat之前将totVal移动,并且如果删除ng-repeat,则它可以工作(我宁愿不更改html的结构,因为这样做会导致很多工作并使设计更糟)。我也曾尝试将totVal移到根范围,但没有成功。

只是绘画/渲染失败,Batarang和console.log总是为我提供更新的值。

有人遇到过这个问题吗?

最佳答案

我不知道这是否正是您要查找的内容,因为我不知道您的用例。
但是,我实现了一个工作示例,请在此处codepen看到。

我对您的代码进行了一些重构,删除了多余的控制器并在服务中封装了totVal。另外,我使用controllerAs语法使内容更清晰。

您的代码存在的问题是totVal是原始元素。因此,当您给它分配一个新值时,角度将无法更新参考。这就是为什么您应该在模型中始终加一个点!

看一下我的代码,您会发现我将totVal声明为var totVal = {val : 0}。我只是更新val,保留引用并正确更新了视图。

.service('totVal', function(){
  var totVal = {val:0};

  this.computeTotVal = function(){
    //perform computations, I will just increment
    totVal.val++;
  }

  this.getTotVal = function() { return totVal; }
})


另请参见此article

07-24 09:30