最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Is it possible to create a directive that acts as a singleton? - Stack Overflow

programmeradmin9浏览0评论

We have a directive as part of our large single page app. We use the same directive in multiple places on the page and each time it acts and looks exactly the same. The main issue we are seeing is that this directive has an ng-repeat which creates a few hundred DOM elements.

Is it possible to create a directive that acts as a singleton? I.e. only has one watch on the collection rather than a watch every time the directive is used or caches the creation of DOM elements to improve speed. Or is there a better way of using the same DOM elements multiple times in the same page.

I've been thinking about using a custom ng-repeat that will cache the html created and reuse it, would this be the best approach?

We have a directive as part of our large single page app. We use the same directive in multiple places on the page and each time it acts and looks exactly the same. The main issue we are seeing is that this directive has an ng-repeat which creates a few hundred DOM elements.

Is it possible to create a directive that acts as a singleton? I.e. only has one watch on the collection rather than a watch every time the directive is used or caches the creation of DOM elements to improve speed. Or is there a better way of using the same DOM elements multiple times in the same page.

I've been thinking about using a custom ng-repeat that will cache the html created and reuse it, would this be the best approach?

Share Improve this question edited Apr 16, 2015 at 20:52 isherwood 61.2k16 gold badges121 silver badges170 bronze badges asked Apr 16, 2015 at 19:42 Mike NorgateMike Norgate 2,4413 gold badges25 silver badges45 bronze badges 1
  • Is it truly independent of parent scope? – Estus Flask Commented Apr 16, 2015 at 20:14
Add a ment  | 

3 Answers 3

Reset to default 3

Angular has a singleton concept in the "service" ponent. You can't make directives singletons (without hackery) but you can totally make services do that - because they are already. The way I would approach this would be to have the service do the data work and expose it to the directive(s). The directives simply access the service, and because services are already singletons, they will all share a single data object/collection/model.

Sure, it is possible, in a sort. Here's an example fiddle:

app.directive('sample', function ($pile, $timeout) {
  var cached;

  return {
    scope: { sampleData: '@', sampleArray: '=' },
    // simple counter for bindings
    controller: function ($scope) {
      $scope.getSampleData = function () {
        console.log('getSampleData');
        return  $scope.sampleData;
      };
    },
    // no overhead for nested directives
    terminal: true,
    template: '<div ng-repeat="n in sampleArray">{{n}} {{::getSampleData()}}</div>Hi! {{::getSampleData()}}',
    pile: function (element) {
      // keeping it wrapped into single element may save you from surprises
      var contents = angular.element('<div>').append(element.contents());
      element.empty();

      return function (scope, element, attrs, ctrl) {        
        cached = cached || $pile(contents)(scope);

        // there's no interpolated template available in post-link, so
        $timeout(function () {
          element.append(cached.clone().contents());
        });

      };
    }
  };
}); 

There's no control over pilation phases, but cached template can be supplied to the directive when it is possible. You may also consider using cache service instead of local variable.

Nobody can guarantee that it won't cause issues. Unless you've already reached performance problems and applied other optimization tricks (I personally found these ones quite inspiring), the mentioned approach should be considered a special case of premature optimization (which is mortal sin).

If you have a problem with number of watches generated by ng-repeat, you should use bindOnce directive (has been native implemented in angular 1.3).

If you have a problem with rendering itself maybe you should consider alternative renderer like ReactJS

发布评论

评论列表(0)

  1. 暂无评论