我有这样的结构(简化了很多):
<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。