bahadir
bahadir

Reputation: 719

Angularjs templateUrl vs template scope issue

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)

Upvotes: 3

Views: 1695

Answers (1)

Estus Flask
Estus Flask

Reputation: 222409

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
    };
});

Upvotes: 3

Related Questions