javascript - Scope inheritance for angular directives - Stack Overflow

I've created a tab control using angular directives. It is consist of tab, tab-itemdirectives wi

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 to demonstrate it.

What is wrong?

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?

Share Improve this question edited Oct 1, 2013 at 9:04 silent_coder 6,53215 gold badges53 silver badges94 bronze badges asked Oct 1, 2013 at 8:44 NatashaNatasha 9731 gold badge10 silver badges24 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 5

(EDIT) Giving some thought after the conversation in the ments, 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 municate 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 mented 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 mented out: http://plnkr.co/edit/tgZqjZk0bRCyZiHKM0Sy?p=preview

http://www.undefinednull./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 e down)

More details on specifying scope to inherit via the last option: What is the difference between & vs @ and = in angularJS

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745332072a4622927.html

相关推荐

  • javascript - Scope inheritance for angular directives - Stack Overflow

    I've created a tab control using angular directives. It is consist of tab, tab-itemdirectives wi

    8小时前
    20

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信