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?
(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.
Comments