我正在开发一个有角度的app / site,现在才意识到无论何时触发模型更改/摘要,都会导致整个页面重新渲染,这看起来很浪费而且很慢。
是否有办法使/限制摘要仅影响其使用的指令/控制器。
例如,如果我有一个"时钟"带有$ interval的指令,用于计算页面上的毫秒数
$scope.page_stats = {"ms_on_page": 0};
$interval(function() {
$scope.page_stats.ms_on_page+= 30;
}, 30);
我的应用布局看起来像这样
<body>
<clock-directive></clock-directive>//<--gets rendered every 30ms
some other html
<some-slow-render-directive></some-slow-render-directive>
// ^-- also gets rendered every 30ms
</body>
如何阻止慢指令每30ms更新一次自身/它的模板,并将时钟间隔摘要限制为时钟指令,因为我知道它不会在页面的任何其他部分使用。 (这不是我的实际应用,只是一个示例来说明我的问题)
答案 0 :(得分:7)
Angular会(通常)重新呈现$rootScope.$digest()
上的所有内容,由$scope.$apply()
,$interval
调用,依此类推。
但是,是一种优化策略,您只能重新渲染适用的部分(高频更新)。
首先,将您的观点分成不同的范围。例如,每30毫秒更新一次的计数器可以在自己的控制器中,使用重指令将其与范围分开。
然后,使用非角度间隔(例如setInterval()
)更新您的值,并手动调用$scope.$digest()
。
例如:
JS:
app.controller('MainCtrl', function($scope, $interval) {
// this is our "heavy" calculation function
// it displays a Unix timestamp, which should change
// every second if the function is continously executed
$scope.calc = function() {
// get time in seconds
return Math.floor(new Date().getTime() / 1000);
};
});
app.controller('ChildCtrl', function($scope, $interval) {
$scope.counter = 0;
// don't use $interval, it'll call $rootScope.$apply()
// uncomment this and comment the setInterval() call
// to see the problem
//$interval(function() { $scope.counter++; }, 1000);
setInterval(function() {
$scope.counter++;
// digest only our scope, without re-rendering everything
$scope.$digest();
}, 1000);
});
HTML:
<body ng-controller="MainCtrl">
<!-- pretend this is our calculation that occurs often -->
<p ng-controller="ChildCtrl">Interval counter: {{ counter }}</p>
<!-- pretend this is our heavy calculation that we don't want to occur often -->
<p>Heavy calc: {{ calc() }}</p>
</body>
在这种情况下,假装calc()
是重指令。您会注意到它只评估过一次,而不是每次计数器更新时。但是,如果您使用$interval
,则每次计数器更新时都会更新。
请注意,必须使用$scope.$digest()
- 如果您使用$scope.$apply()
,则会调用$rootScope.$digest()
,这将更新所有内容。
进一步阅读here。