Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS: templateUrl defers construction of controller, dependent code breaks

So I just started using AngularJS, and it seems perfectly fine so far, aside from one little snag. Let's say I have two directives, one of which requires the other, like so:

angular.module('components', [])
    .directive('outer', function() {
        return {
            restrict: 'E',
            replace: true,
            transclude: true,
            scope: {},
            link: function(scope) { ... },
            controller: function($scope) { ... },
            templateUrl: 'outer.html' // Note this
        };
    })
    .directive('inner', function() {
        return {
            require: '^outer', // And this
            restrict: 'E',
            ...
            link: function(scope, element, attrs, outerCtrl) { ... },
            templateUrl: 'inner.html'
        };
    });

used in the HTML something like this:

<outer>
    <inner></inner>
</outer>

If outer.html loads before inner.html, then there is no problem at all. <outer> is transformed correctly and is assigned a scope and a controller, and <inner> receives that controller just fine.

If the templates load in the opposite order, however, <inner> is linked before <outer>’s controller has been created, and it fails with the error message “Error: no controller: outer”.

I have tried attaching a server-side load delay to inner.html, and as long as outer.html loads first, there are no problems anywhere whatsoever. Similarly, if I inline outer’s template (i.e. using template instead of templateUrl), that template becomes available first and it all works splendidly.

Does anyone know of a way to use templateUrl on directives that are required by other directives? In my actual code, it is vital that the inner directive have access to the outer’s controller, and I’d rather prefer templateUrl over template because the former separates layout from behaviour, and makes it much easier to configure the templates even after the behavioural code has grown large.

Thanks in advance, and sorry if this has already been asked before; I couldn’t find any equivalent questions on Stack Overflow.

like image 313
Adam Heurlin Avatar asked Nov 03 '22 18:11

Adam Heurlin


1 Answers

When you define multiple directives within a same module, you can assign a priority which takes care of the order in which the directives should be executed. In you case, give the 'outer' more priority that the inner. So irrespective of when the template loads, the directives are executed in order.

look at 'Directive Definition Object' in directive for more explanation.

I hope that answers.

However, when you say that the 'outer' controller depends on the 'inner' controller, it doesn't look good. In my personal opinion, a controller should not be tied up with another controller. I am not sure about your use case, but there should be a way to break the dependency between the two controllers.

like image 121
manoj Avatar answered Nov 11 '22 12:11

manoj