如何将角度摘要限制为仅影响/重新渲染一个组件/指令

Rai*_*mer 1 html javascript angularjs

我正在开发一个角度app/site,现在才意识到每当触发模型更改/摘要时,它会导致整个页面重新渲染,这看起来很浪费而且很慢.

有没有办法导致/限制摘要只影响它使用的指令/控制器.

例如,如果我有一个带有$ interval的"clock"指令来计算页面上的毫秒数

$scope.page_stats = {"ms_on_page": 0};
$interval(function() {
    $scope.page_stats.ms_on_page+= 30;
}, 30);
Run Code Online (Sandbox Code Playgroud)

我的应用程序布局看起来像这样

<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>
Run Code Online (Sandbox Code Playgroud)

我如何阻止慢指令每30ms更新一次自己/它的模板,并将时钟间隔摘要限制为时钟指令,因为我知道它不会在页面的任何其他部分使用.(这不是我的实际应用,只是一个示例来说明我的问题)

Ago*_*gop 7

Angular将(通常)重新渲染所有内容$rootScope.$digest(),由$scope.$apply(),调用$interval,等等.

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

首先,将您的视图分成不同的范围.例如,每30 ms更新一次的计数器可以在自己的控制器中,使用重指令将其与范围分开.

然后,使用非角度间隔(例如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);
});
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

Plunker

在这种情况下,假装这calc()是重指令.您会注意到它只评估一次,而不是每次计数器更新.但是,如果您使用$interval,则每次计数器更新时都会更新.

请注意,您必须使用$scope.$digest()- 如果您使用$scope.$apply(),它将调用$rootScope.$digest(),这将更新所有内容.

进一步阅读这里.