Scope Inheritance For Angular Directives
Solution 1:
(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 thetabItem
for thetabItemHeader
andtabItemBody
).
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
Solution 2:
http://www.undefinednull.com/2014/02/11/mastering-the-scope-of-a-directive-in-angularjs/
This site explains scope inheritance very well.
Basically, if you add a scope section to the directive that you want to have you have a few options:
scope:false# this inherits the parent scope and allows upstream and downstream traffic (parent <=> child)scope:true# this inherits the parent scope and allows downstream traffic (parent => child)scope: {} # this does not inherit and creates the directive's very own scope (you can still inherit by specifying what you want to come down)
More details on specifying scope to inherit via the last option: What is the difference between & vs @ and = in angularJS
Post a Comment for "Scope Inheritance For Angular Directives"