Angular 1.5 中的多级嵌入
Posted
技术标签:
【中文标题】Angular 1.5 中的多级嵌入【英文标题】:Multilevel transclusion in Angular 1.5 【发布时间】:2016-05-21 04:27:49 【问题描述】:我有一个通用的<item>
指令和一个带有过滤器和分页工具的<listing>
指令,用于列出<item>
:
示例:https://plnkr.co/edit/r6byzhFX5m674ONhH1JS?p=preview
<listing>
模板是这样的:
<div ng-repeat="item in items">
<item date="item">
<ng-transclude ng-transclude-slot="itemContent"></ng-transclude>
</item>
</div>
<item>
指令使用新的 Angular 1.5 多槽嵌入来轻松自定义页脚和页眉:
<item data="itemData">
<header>My header</header>
<footer>My custom footer</footer>
</item>
当我在使用<listing>
时尝试自定义这些项目时,出现了我的问题。如果我使用这样的东西:
<listing items="myItems">
<item-content>
<header> item.name </header>
<footer>My custom footer for item.name </footer>
</item-content>
</listing>
它不起作用,因为<item-content>
被插入到<item>
,但<header>
和<footer>
没有被嵌入到它们的适当位置,它们无法读取item
范围变量。有什么方法可以实现吗?
【问题讨论】:
你能为此创建一个 plnker 或 fiddle 吗?想进一步研究这个问题。 这里是:plnkr.co/edit/r6byzhFX5m674ONhH1JS?p=preview 据我所知,您正在尝试做的事情是行不通的。根据设计,transclude 改变了范围嵌套的方式。它使嵌入指令的内容具有指令外部的任何范围,而不是内部的任何范围。它使内容可以访问外部范围。因此,在您的示例中,<item-header>
和 <item-footer>
中的嵌入内容访问控制器范围。可能有一种方法可以使用link
的transcludeFn
参数来解决这个问题。但我不确定transcludeFn
如何与多槽功能配合使用。
我想我找到了解决方案。将在今天晚些时候回复。
我会等你的帖子
【参考方案1】:
首先,在列表模板中,您应该将 ng-transclude-slot="itemHeader"
更改为 ng-transclude="itemHeader"
并将 ng-transclude-slot="itemFooter"
更改为 ng-transclude="itemFooter"
以使嵌入工作。
那么,您在单例和列表示例中出现了错误。如果您在单个示例中将提供的 plunkr items[0].name
更改为预期的 data.name
,您将看到该名称不再显示。第二件事是解决这个共同的问题。
【讨论】:
没错,我使用的是ng-transclude-slot
,而应该使用ng-transclude
。我已经更新了plunker。关于如何解决共享问题的任何想法?
请查看以下问题是否有帮助:***.com/questions/18794968/… 和 ***.com/questions/14049480/…【参考方案2】:
TL;DR;工作示例: https://plnkr.co/edit/1ideOiohle8AEzkDJ333?p=preview
您遇到的基本问题是,当您进行转换时,您可以访问的范围是***范围。您想要的是从指令外部引用项目级别范围。
因此,我没有在列表指令上使用嵌入,而是将字符串模板绑定为属性。在 angular 提取 占位符之前,我必须使用编译函数来获取原始字符串值,然后我使用
$interpolate
创建模板函数 itemHeaderTemplate
和 itemFooterTemplate
,然后像这样在模板中使用ng-bind-html="itemHeaderTemplate(item: item)"
.
注意:要使用ng-bind-html
,您需要包含ngSanitize
模块,否则您会遇到安全异常。
【讨论】:
以上是关于Angular 1.5 中的多级嵌入的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Angular 1.5 组件中使用多槽透入,或者改用啥?