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

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

问题描述

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

它加载了 30 个项目,这些数据一旦加载就是静态的,所以不需要双重数据绑定.

问题是该页面上的观察者数量保持不变,无论我怎么做.

假设:

<小时>

//这里什么都没有

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

<小时>

//这里什么都没有

观察者数量仍然是211(如果我理解正确的话应该是210),但是等等:

<小时>

{{stuff.id}}

观察者数量现在是 241(好吧,211 个观察者 + 30 个东西 * 1 个观察者 = 241 个观察者)

<小时>

{{::stuff.id}}

观察者数量仍然是241!!!:: 不应该删除关联的观察者吗??

<小时>

{{stuff.id}} {{stuff.name}} {{stuff.desc}}

还是241...

<小时>

这些例子确实是在我的应用中制作的,所以这些数字也是真实的.

真正的 ng-repeat 比这里的示例复杂得多,我的页面上有大约 1500 个观察者.如果我删除其内容(如示例中所示),我将下降到大约 200 个观察者.那么我该如何优化它呢?为什么 :: 似乎不起作用?

谢谢你赐教...

解决方案

在您的具体情况下很难弄清楚确切的问题是什么,也许提供一个孤立的例子是有意义的,以便其他人可以提供帮助.

结果可能取决于您如何计算观察者.我从这里获得解决方案.

这是一个Plunker示例按预期工作(添加或删除::ng-repeat) 中:

HTML

<html ng-app="app"><头><script data-require="angular.js@1.5.6" data-semver="1.5.6" src="https://code.angularjs.org/1.5.6/angular.min.js"><link rel="stylesheet" href="style.css"/><script src="script.js"></script><body ng-controller="mainCtrl"><div>{{name}}</div><ul><li ng-repeat="item in ::items">{{::item.id}} - {{::item.name}}</li><button id="watchersCountBtn">显示观察者计数</button><div id="watchersCountLog"></div></html>

JavaScript

角度.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' }];});函数 getWatchers(root) {root = angular.element(root || document.documentElement);var watcherCount = 0;函数 getElemWatchers(元素){varisolateWatchers = getWatchersFromScope(element.data().$isolateScope);var scopeWatchers = getWatchersFromScope(element.data().$scope);var watchers = scopeWatchers.concat(isolateWatchers);angular.forEach(element.children(), 函数 (childElement) {watchers = watchers.concat(getElemWatchers(angular.element(childElement)));});返回观察者;}函数 getWatchersFromScope(范围){如果(范围){返回范围.$$watchers ||[];} 别的 {返回 [];}}返回 getElemWatchers(root);}window.onload = function() {var btn = document.getElementById('watchersCountBtn');var log = document.getElementById('watchersCountLog');window.addEventListener('click', function() {log.innerText = getWatchers().length;});};

希望这会有所帮助.

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

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.

Let say :


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

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>

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>

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


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

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>

Still 241...


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

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 ?

Thank you to enlighten me...

解决方案

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.

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

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;
  });
};

Hope this helps.

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

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