无法减少ng-repeat中的观察者数量 [英] Unable to reduce the number of watchers in ng-repeat

查看:52
本文介绍了无法减少ng-repeat中的观察者数量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

出于性能目的,我想从ng-repeat中删除双重数据绑定(因此,关联的观察者).

In a performance purpose, i wanted to remove the double data-binding (so, the associated watchers) from my ng-repeat.

它可以加载30个项目,并且这些数据在加载后是静态的,因此不需要双重数据绑定.

It loads 30 items, and those data are static once loaded, so no need for double data binding.

问题是,无论我如何操作,该页面上的观察者数量都保持不变.

The thing is that the watcher amount remains the same on that page, no matter how i do it.

说:

<div ng-repeat='stuff in stuffs'>
   // nothing in here
</div>

观察者数量为 211 (该页面上还有其他绑定,而不仅仅是ng-repeat)

Watchers amount is 211 (there is other binding on that page, not only ng-repeat)

<div ng-repeat='stuff in ::stuffs'>
   // nothing in here
</div>

观察者数量仍为 211 (如果我理解正确,应为 210 ),但请等待:

Watchers amount is still 211 ( it should be 210 if i understand it right), but wait :

<div ng-repeat='stuff in ::stuffs'>
    {{stuff.id}}
</div>

观察者数量现在为 241 (好吧,211个观察者+ 30个物品* 1个观察者= 241个观察者)

Watchers amount is now 241 (well ok, 211 watchers + 30 stuffs * 1 watcher = 241 watchers)

<div ng-repeat='stuff in ::stuffs'>
    {{::stuff.id}}
</div>

观察者数量仍为 241 !!! ::不应该删除关联的观察程序?

Watchers amount is still 241 !!! Is :: not supposed to remove associated watcher ??

<div ng-repeat='stuff in ::stuffs'>
    {{stuff.id}}  {{stuff.name}}  {{stuff.desc}}
</div>

仍然 241 ...

这些示例确实是在我的应用中完成的,因此这些数字也是真实的.

Those exemples has really been made in my app, so those numbers are real too.

真正的ng-repeat远比这里的示例复杂,我的页面上吸引了约1500位观看者.如果我删除了它的内容(例如在示例中),我将跌落到200个观察者.那么我该如何优化呢?为什么::似乎不起作用?

The real ng-repeat is far more complex than the exemple one here, and i reach ~1500 watchers on my page. If i delete its content ( like in the exemple), i fall down to ~200 watchers. So how can i optimize it ? Why :: does't seem to work ?

谢谢启发...

推荐答案

很难弄清特定情况下的确切问题,也许有一个孤立的例子很有意义,以便其他人可以提供帮助.

It's hard to figure out what's the exact problem in your specific case, maybe it makes sense to provide an isolated example, so that other guys can help.

结果可能取决于您对观察者的计数方式.我从此处获取了解决方案.

The result might depend on how you count the watchers. I took solution from here.

以下是一个Plunker示例正常工作(在ng-repeat中添加或删除::) :

Here is a Plunker example working as expected (add or remove :: in ng-repeat):

HTML

<!DOCTYPE html>
<html ng-app="app">
  <head>
    <script data-require="angular.js@1.5.6" data-semver="1.5.6" src="https://code.angularjs.org/1.5.6/angular.min.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>
  <body ng-controller="mainCtrl">
    <div>{{name}}</div>

    <ul>
      <li ng-repeat="item in ::items">{{::item.id}} - {{::item.name}}</li>
    </ul>

    <button id="watchersCountBtn">Show watchers count</button>
    <div id="watchersCountLog"></div>
  </body>
</html>

JavaScript

JavaScript

angular
  .module('app', [])
  .controller('mainCtrl', function($scope) {
    $scope.name = 'Hello World';

    $scope.items = [
      { id: 1, name: 'product 1' },
      { id: 2, name: 'product 2' },
      { id: 3, name: 'product 3' },
      { id: 4, name: 'product 4' },
      { id: 5, name: 'product 5' },
      { id: 6, name: 'product 6' },
      { id: 7, name: 'product 7' },
      { id: 8, name: 'product 8' },
      { id: 9, name: 'product 9' },
      { id: 10, name: 'product 10' }
    ];
  });

function getWatchers(root) {
  root = angular.element(root || document.documentElement);
  var watcherCount = 0;

  function getElemWatchers(element) {
    var isolateWatchers = getWatchersFromScope(element.data().$isolateScope);
    var scopeWatchers = getWatchersFromScope(element.data().$scope);
    var watchers = scopeWatchers.concat(isolateWatchers);
    angular.forEach(element.children(), function (childElement) {
      watchers = watchers.concat(getElemWatchers(angular.element(childElement)));
    });
    return watchers;
  }

  function getWatchersFromScope(scope) {
    if (scope) {
      return scope.$$watchers || [];
    } else {
      return [];
    }
  }

  return getElemWatchers(root);
}

window.onload = function() {
  var btn = document.getElementById('watchersCountBtn');
  var log = document.getElementById('watchersCountLog');

  window.addEventListener('click', function() {
    log.innerText = getWatchers().length;
  });
};

希望这会有所帮助.

这篇关于无法减少ng-repeat中的观察者数量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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