如何限制角消化,只影响/重新渲染一个组件/指令 [英] How to limit angular digest to only effect/re-render one component/directive

查看:130
本文介绍了如何限制角消化,只影响/重新渲染一个组件/指令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是开发一个角度应用程序/网站,现在才意识到,每当模型更改/触发消化,它会导致整个页面重新渲染,这似乎浪费和缓慢的。

I was developing an angular app/site, and only now realized that whenever a model changes/digest is triggered, it causes the whole page to re-render, which seems wasteful and slow.

有没有办法使/限制消化,可以只影响指令/控制器,它是在使用。

Is there a way to cause/limit digest to only affect the directive/controller it is used in.

例如,如果我有$间隔时钟指令到一个页面上数毫秒

e.g if i have a "clock" directive with $interval to count milliseconds on a page

$scope.page_stats = {"ms_on_page": 0};
$interval(function() {
    $scope.page_stats.ms_on_page+= 30;
}, 30);

和我的应用程序的布局看上去像这样

and my app layout looked like this

<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>

我将如何停止缓慢指令从更新自己,/它的每一个30毫秒的模板,并限制时钟间隔只消化到时钟指令,因为我知道它不会在页面的任何其他部分使用。 (这不是我的实际应用,只是一个样本来说明我的问题)

How would i stop the slow directive from updating itself/its template every 30ms , and limit the clock interval digest only to the clock directive since i know it wont be used in any other part of the page. ( this isn't my actual app, just a sample to illustrate my question)

推荐答案

角(通常)重新渲染上 $ rootScope一切。$摘要(),这是通过 $范围调用。$适用() $间隔,等等。

Angular will (usually) re-render everything on $rootScope.$digest(), which is called by $scope.$apply(), $interval, and so on.

然而,的你可以只适用于重新呈现适用部分(高频更新)的优化策略。

However, there is an optimization strategy you can apply to only re-render the applicable portions (the high frequency updates).

首先,独立的意见分成​​不同的范围。例如,每30毫秒更新计数器可以是在它自己的控制器,从范围与重指令中分离出来。

First, separate your views into different scopes. For example, the counter that updates every 30 ms could be in its own controller, separating it from the scope with the heavy directive.

然后,使用非角区间(例如的setInterval())来更新你的价值,并调用 $范围。$摘要() 手动

Then, use a non-Angular interval (e.g. setInterval()) to update your value, and call $scope.$digest() manually.

例如:

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>

Plunker

在这种情况下,pretend的钙()是沉重的指令。你会发现,它不是每次只计算一次,计数器的更新。但是,如果你使用 $间隔,它会更新每次计数器更新。

In this case, pretend that calc() is the heavy directive. You'll notice that it's only evaluated once, not every time the counter updates. However, if you use $interval, it'll update every time the counter updates.

请注意,您的必须的使用 $范围$摘要() - 。如果你使用 $范围$申请(),它会调用 $ rootScope。$摘要(),将更新的一切。

Note that you must use $scope.$digest() - if you use $scope.$apply(), it will call $rootScope.$digest(), which will update everything.

延伸阅读这里

这篇关于如何限制角消化,只影响/重新渲染一个组件/指令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆