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

javascript - AngularJS directive - setting order for multiple directive elements (not priority for directives, but priority for

programmeradmin1浏览0评论

Considering this markup with a directive "foo":

<div foo run="3"></div>
<div foo run="1"></div>
<div foo run="2"></div>

What is a good approach for causing "foo" to run in the specified order rather than from top to bottom (3,1,2)? The only thing I can think to do would be tracking what has run and returning false on the items that are not in order, then making angular try to run them all again and repeat until they are all done. That sounds terrible to me though, because it would have to repeat so many times... Does Angular have something built-in that can be used? Is there an ideal approach for dealing with this?

Considering this markup with a directive "foo":

<div foo run="3"></div>
<div foo run="1"></div>
<div foo run="2"></div>

What is a good approach for causing "foo" to run in the specified order rather than from top to bottom (3,1,2)? The only thing I can think to do would be tracking what has run and returning false on the items that are not in order, then making angular try to run them all again and repeat until they are all done. That sounds terrible to me though, because it would have to repeat so many times... Does Angular have something built-in that can be used? Is there an ideal approach for dealing with this?

Share Improve this question edited May 1, 2016 at 7:16 Cindy Meister 25.7k21 gold badges36 silver badges44 bronze badges asked Aug 5, 2013 at 2:42 m59m59 43.8k14 gold badges121 silver badges139 bronze badges 3
  • 1 I think it would be helpful to have a little more information about what you are doing within the foo directive, and how the order is important. With a parent directive, you may be able to capture the child directives, then process them in a separate step. – OverZealous Commented Aug 5, 2013 at 2:57
  • Hmm. That's an interesting thought. I'll crunch on it for a bit. What my actual directive is doing is loading various kinds of content, some of which is drastically more important than others. It's actually a plugin loader and deals with lazy loading of controllers/templates. It has all loaded very quickly so far, but I want to try it with a good priority system in place also. At the moment, the content just loads from top to bottom. This could be an issue where there is a left side-bar that would take priority over the main content body. – m59 Commented Aug 5, 2013 at 3:03
  • I see, you mean remotely requested content, and you want to manage the load order? – OverZealous Commented Aug 5, 2013 at 3:06
Add a ment  | 

2 Answers 2

Reset to default 3

OK, here's my solution, although it's more a template.

Fiddle (check the console log to see the result)

I've wrapped the foo directive in a fooParent directive, like so:

<div foo-parent>
    <div foo run="3"></div>
    <div foo run="1"></div>
    <div foo run="2"></div>
</div>

The fooParent directive exists pretty much to do three things:

  1. Expose a function to foo items so they can be added to a general list
  2. Maintain a list of foos, which will be sorted during post-linking
  3. Process each foo in the run order specified.

It looks like this:

app.directive('fooParent', function() {
    var foos = [];
    return {
        restrict: 'A',
        controller: ['$scope', '$element', '$attrs', '$transclude', function($scope, $element, $attrs, $transclude) {
            this.addFoo = function(runOrder, element) {
                foos.push({
                    run: 1*runOrder, // make sure run is an integer
                    element: element
                });
            };
        }],
        link: function(scope, element, attrs) {
            foos.sort(function(a, b) {
                return a.run - b.run;
            });
            // process all children here
            angular.forEach(foos, function(foo) {
                console.log(foo);
            });
        }
    };
});

And foo simply looks like:

app.directive('foo', function() {
    return {
        restrict: 'A',
        require: '^fooParent',
        link: function(scope, element, attrs, fooParent) {
            fooParent.addFoo(attrs.run, element);
        }
    };
});

Obviously, you will have to figure out the best way to handle remotely loading your content, especially if you want it to be serially loaded. Your foo directive would bee much more simplified, since the loading and processing would have to occur within fooParent.

Credit to OverZealous for inspiring my answer. Test it here. http://jsbin./apumaj/21/edit

the html (directive output will be displayed in this order, of course)

<div foo run="7"></div>
<div foo run="3"></div>
<div foo run="1"></div>
<div foo run="2"></div>

and the directive (to make the directive output load in "run" order) should be self-explanatory

app.directive('foo', function() {
  var foos = [];
  var foosLength = document.querySelectorAll('[foo]').length;
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
          foos.push({element:element, run:attrs.run});
          if (foos.length === foosLength) {
             foos.sort(function(a, b) {
                return a.run - b.run;
            });
            console.log('ran in this order:');
            for (var i=0; i<foosLength; ++i) {
              //process foos!
              var foo = foos[i];
              console.log(foo.run);
              foo.element.text(foo.run);
            }
          }
        }
    };
});

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论