Scope inheritance for angular directives

Natasha

I've created a tab control using angular directives. It is consist of tab, tab-item directives with new scope and tab-item-header, tab-item-body directives for which scope is not declared.

If I understand correctly these directives use scope of tab-item directive because they are placed inside it. But when I try to get in markup property index which is declared inside tab-item scope it is undefined.

app.directive('tabItemHeader', function(){
return {
    require: '^tabItem',
    transclude: true,
    template: '<div ng-click="$parent.setCurrentTab(index)" ng-transclude></div>',
};});

app.directive('tabItemBody', function(){
return {
    require: '^tabItem',
    transclude: true,
    template: '<div ng-show="index==$parent.currentTabIndex"><div ng-transclude></div></div>'
};});

I've created a plunk http://plnkr.co/edit/HkXIOt8FKMw4Ja2GZtF1?p=preview to demonstrate it.

What is wrong?

Nikos Paraskevopoulos

(EDIT) Giving some thought after the conversation in the comments, I came up with a better solution. Here is the modified plunk:

http://plnkr.co/edit/djNk8PPzXvngZOvAirMu?p=preview

The key points of this implementation are:

  • Every directive transcludes its content. This means that, even the innermost directives have access to the outer scope, as is expected. So no more $parent.$parent... awfulness.

  • Every directive has an isolated scope. As per the docs the isolated scope is side-by-side with the transcluded one; therefore all the private state of the directives (in this case the active tab, the index of each tabItem and some directive-specific functions) is kept in the isolated scope.

  • The directives communicate through the controllers. This pattern requires a top level "coordinator" (here the tab for all descendant directives and the tabItem for the tabItemHeader and tabItemBody).

By the way, if you want tabs, I would suggest Angular UI.


This was a crazy puzzler.

The reason for your problem is that the tabItem directive had no reason to transclude its contents; this transclusion created a sibling scope that totally messed up your logic!

Thus the answer is simple: remove these lines from the tabItem directive:

// REMOVE THEM!!!
transclude: true,
template: '<div ng-transclude></div>',

A plunkr with these lines commented out that prints scope ids: http://plnkr.co/edit/bBfEej145s1YjcE9n3Lj?p=preview (this helps with debugging; see what happens when you include these lines, the templates and the linker function see different scopes!)

And your plunkr forked, with those lines commented out: http://plnkr.co/edit/tgZqjZk0bRCyZiHKM0Sy?p=preview

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Scope inheritance for angular directives

From Dev

AngularJS : Nested Directives and Scope Inheritance

From Dev

angular scope in controllers + directives

From Dev

Angular Directives: scope vs bindToController

From Dev

Multiple custom directives scope in Angular

From Dev

Nested directives, scope inheritance, and watching values between parent and child

From Dev

Nested Angular directives triggering scope functions on parents

From Dev

Angular How to access controller scope from directives

From Dev

Angular:How to pass scope data to directives

From Dev

Scope in directives

From Dev

Scope in directives

From Dev

how angular controller (and scope) inheritance works

From Dev

Angular controller scope inheritance vs service

From Dev

Angular Directive scope inheritance inside attributes

From Dev

how angular controller (and scope) inheritance works

From Dev

Angular error in Firefox only "Multiple directives asking for isolated scope"

From Dev

Binding functions through nested directives with isolated scope failing in Angular 1.4

From Dev

How to update Angular scope properties when they are passed into directives?

From Dev

Directives, Isolated scopes, Inheritance

From Dev

controllerAs with directives and isolated scope

From Dev

Scope Isolation & nested directives

From Dev

AngularJS : directives and scope

From Dev

Isolated scope for directives

From Dev

AngularJs scope reference with directives

From Dev

bind $scope in Directives/Controller

From Dev

bind $scope in Directives/Controller

From Dev

Angular directives

From Dev

Inheritance w/ Angular's 'Controller As' vs. $scope

From Dev

Inheritance in AngularJs Directives link function

Related Related

HotTag

Archive