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

angularjs, angularjs-directive, element, javascript, order-of-execution

Solution

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:

- Expose a function to `foo` items so they can be added to a general list

- Maintain a list of `foos`, which will be sorted during post-linking

- 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 become much more simplified, since the loading and processing would have to occur within `fooParent`.

Problem

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?

Original source