3

I ran into a strange behaviour on angular. when creating a directive if i use

 mod.directive('test', [function(){
     return {
         restrict: 'E',
         templateUrl: '/test/test.html',
         transclude: true,
         controller: ['$scope',function($scope){
             //$scope equals containing scope of directive. why???
         }]
     };
 }]);

$scope is the same scope (not inherited) as containing scope of directive.

but if i create directive as

 mod.directive('test', [function(){
     return {
         restrict: 'E',
         template: '<div><div ng-transclude /></div>',
         transclude: true,
         controller: ['$scope',function($scope){
             //$scope is new. inherited from container scope
         }]
     };
 }]);

only difference is template vs templateUrl. "templateUrl" one uses parent scope but "template" one creates a new scope. i dont understand why. could this be an angular bug?

thanks already

Edit: i am using Angular 1.3.0-beta.7

Big-Edit: i am using another directive on same element as @estus mentioned.

<test other-directive></test>

other-directive is defined as scope:true. but it doesn't create a new scope when used with templateUrl on test directive.

Edit: Sample plnkr http://plnkr.co/edit/Kghah1rvwFE6TSw85Cog?p=preview (templateUrl)

plnkr -> http://plnkr.co/edit/Axiye1ksBMR8dp9ND8tL?p=preview (template)

1 Answer 1

3

This is confusing but expected behaviour for a directive with asynchronously loaded template (via templateUrl):

Because template loading is asynchronous the compiler will suspend compilation of directives on that element for later when the template has been resolved. In the meantime it will continue to compile and link sibling and parent elements as though this element had not contained any directives.

To get around this issue use priority to compile the directive with new scope in the first place:

app.directive('directiveOne', function () {
     return {
         restrict: 'E',
         templateUrl: 'directive-template.html',
         transclude: true,
         controller: ['$scope', function($scope){
         ...
         }]
     };
});

app.directive('directiveTwo', function () {
     return {
         priority: 100,
         scope: true
    };
});
Sign up to request clarification or add additional context in comments.

8 Comments

yeah there is another directive on same element. see edited question pls
Updated the answer. What did make you think that the directive with templateUrl doesn't have a new scope?
i'll post a working plunkr tomorrow at office. my codes arent with me now.
i added plnkr to question
I see. Yes, cached templates aren't illustrative here, because when the directive is being compiled the first time, its template will be loaded asynchronously. I've updated the answer to match the question.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.