2

我使用角度指令创建了一个选项卡控件。它由 具有新范围的tabtab-item指令和未声明范围的tab-item-headertab-item-body指令组成。

如果我理解正确,这些指令使用 tab-item 指令的范围,因为它们被放置在其中。但是,当我尝试进入在选项卡项范围内声明的标记属性索引时,它是未定义的。

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

我创建了一个 plunk http://plnkr.co/edit/HkXIOt8FKMw4Ja2GZtF1?p=preview来演示它。

怎么了?

4

2 回答 2

5

(编辑)在评论中的对话后考虑一下,我想出了一个更好的解决方案。这是修改后的plunk:

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

这个实现的关键点是:

  • 每个指令都包含其内容。这意味着,正如预期的那样,即使是最内部的指令也可以访问外部范围。所以没有更多的$parent.$parent...可怕。

  • 每个指令都有一个独立的范围。根据文档,孤立的范围与嵌入的范围并排;因此,指令的所有私有状态(在本例中为活动选项卡、每个指令的索引tabItem以及一些特定于指令的函数)都保持在隔离范围内。

  • 这些指令通过控制器进行通信。这种模式需要一个顶级的“协调器”(这里是tabfor all 后代指令和tabItemfor the tabItemHeaderand tabItemBody)。

顺便说一句,如果你想要标签,我建议使用 Angular UI。


这是一个疯狂的谜题。

您的问题的原因是该tabItem指令没有理由嵌入其内容;这个嵌入创建了一个兄弟范围,完全搞乱了你的逻辑!

因此答案很简单:从tabItem指令中删除这些行:

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

带有这些行的 plunkr 注释掉了打印范围 ID:http ://plnkr.co/edit/bBfEej145s1YjcE9n3Lj?p=preview (这有助于调试;看看包含这些行时会发生什么,模板和链接器函数会有所不同范围!)

你的 plunkr 分叉了,这些行被注释掉了:http ://plnkr.co/edit/tgZqjZk0bRCyZiHKM0Sy?p=preview

于 2013-10-01T09:35:15.417 回答
4

http://www.undefinednull.com/2014/02/11/mastering-the-scope-of-a-directive-in-angularjs/

该站点很好地解释了范围继承。

基本上,如果您将范围部分添加到您想要的指令中,您有几个选项:

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)

有关通过最后一个选项指定要继承的范围的更多详细信息:AngularJS 中的 & vs @ 和 = 有什么区别

于 2014-07-31T15:49:11.587 回答