2017-05-23 33 views
0

我正在研究增强角度摘要循环的选项。角度摘要循环的高级提升

我在任何给定的时间与数万活跃观察家一个相当复杂的应用程序。

作为我注册上滚动事件(和在动画帧处理它们)的应用程序的功能的一部分,所以该摘要每个滚动,这导致以fps偶尔降基本上执行。

我已经减少了观察家们一次性绑定算,现在我只剩下几千观察家。

目前,我试图写一个指令暂停了视元素的所有观察者。

于是我开始用角内部玩耍,并与下面的指令上来:

app.directive('ngSuspendable', function() { 
    return { 
     restrict: 'A', 
     scope: true, 
     link: function (scope, element, attr) { 
      var _watchersMap = {}; 
      var _suspended = true; 
      suspendWatchersTree(); 

      function suspendWatchersTreeRecursive(currentScope, includeSiblings) { 
       while (currentScope != null) { 
        if ((currentScope.$$watchers != null) && 
         (currentScope.$$watchers.length > 0) && 
         (typeof _watchersMap[currentScope.$id] == "undefined")) { 
         _watchersMap[currentScope.$id] = currentScope.$$watchers; 
         currentScope.$$watchers = []; 
        } 

        if (currentScope.$$childHead != null) { 
         suspendWatchersTreeRecursive(currentScope.$$childHead, true); 
        } 

        if (includeSiblings) { 
         currentScope = currentScope.$$nextSibling; 
        } 

        else { 
         currentScope = null; 
        } 
       } 
      } 

      function unsuspendWatchersTreeRecursive(currentScope, includeSiblings) { 
       while (currentScope != null) { 
        if ((typeof _watchersMap[currentScope.$id] != "undefined") && 
         (_watchersMap[currentScope.$id].length > 0)) { 
         if ((currentScope.$$watchers != null) && 
          (currentScope.$$watchers.length > 0)) { 
          currentScope.$$watchers = currentScope.$$watchers.concat(_watchersMap[currentScope.$id]); 
         } 

         else { 
          currentScope.$$watchers = _watchersMap[currentScope.$id]; 
         } 
        } 

        if (currentScope.$$childHead != null) { 
         unsuspendWatchersTreeRecursive(currentScope.$$childHead, true); 
        } 

        if (includeSiblings) { 
         currentScope = currentScope.$$nextSibling; 
        } 

        else { 
         currentScope = null; 
        } 
       } 
      } 

      function suspendWatchersTree() { 
       suspendWatchersTreeRecursive(scope, false); 
      } 

      function unsuspendWatchersTree() { 
       unsuspendWatchersTreeRecursive(scope, false); 
      } 

      scope.inView = function(evnt, model, htmlElementId, triggeringEvent, isInView, inViewPart) { 
       if (!isInView) { 
        suspendWatchersTree(); 
        _suspended = true; 
       } 

       if ((isInView) && (_suspended)) { 
        unsuspendWatchersTree(); 
        _watchersMap = {}; 
        _suspended = false; 
       } 
      } 
     } 
    } 
}); 

在初始化这个指令将删除当前范围内的所有观察者和所有子范围(不知道是否捕捉也隔离示波器) 。 然后,当元素在视图中时,它会添加观察者,并在观察视线时将其删除。

我知道它并不一定会捕获所有的观察者,因为有些观察者可能会在链接后添加,但这似乎可以忽略不计,并且一旦元素进入视图并再次出现视图,它们将被删除。如果我能以某种方式挂钩观察者添加并将它们添加到地图中,但是我猜测它不是必须的。

这似乎是工作很好,但我不知道什么是这种方法的注意事项。我对玩弄有角度的内部装置和弄乱事物并造成不稳定状况感到不舒服。

任何想法和意见,将不胜感激。

+1

听起来像你想要的是[codereview.se]。询问工作代码的好网站。请务必阅读他们的帮助中心,以确保您的问题与主题相关。 –

回答

0

我已经使用最近的更改更新了上述代码。 进一步测试表明它工作得很好,有些手表可能不会在初始化时暂停,但这是我可以接受的价格。它大大增强了我的摘要循环,并通过从视口元素中移除不需要的手表来提升应用性能。