如何在 ember.js 组件模板中生成多条内容?
Posted
技术标签:
【中文标题】如何在 ember.js 组件模板中生成多条内容?【英文标题】:How can I yield multiple pieces of content into an ember.js component template? 【发布时间】:2015-07-28 17:28:51 【问题描述】:目标是定义一种 html 结构,其中包含多个由调用者声明的内容块。例如,标题、正文和内容。生成的标记应该是:
<header>My header</header>
<div class="body">My body</div>
<footer>My footer</footer>
实例化组件的模板将定义三个部分中的每一个,My header
、My body
和 My footer
。
使用 Ruby on Rails,您可以使用 content_for :header
捕获来自调用者的标头内容,并使用 yield :header
对其进行插值。
这在 ember.js 中可行吗?
【问题讨论】:
【参考方案1】:从 ember v1.10 开始,yield 接受参数。然而,handlebars 还不允许对变量值进行内联比较。通过在组件上定义一些属性,我们可以非常接近 rails 的功能。
根据上面的示例,组件的模板如下所示:
<header>yield header</header>
<div class="body">yield body</div>
<footer>yield footer</footer>
并且组件定义会将变量参数解析为 yield 语句:
export default Ember.Component.extend(
header: isHeader: true,
footer: isFooter: true,
body: isBody: true
);
这意味着yield header
实际上正在向消费模板生成一个对象isHeader: true
。所以我们可以使用嵌套的 if/else 结构来声明这三个部分,如下所示:
#my-comp as |section|
#if section.isHeader
My header
else if section.isBody
My body
else if section.isFooter
My footer
/if
/my-comp
【讨论】:
这可以进一步简化以消除对组件中对象定义的需要。通过使用ember-truth-helpers
插件,您可以在组件模板中使用yield 'header'
,然后在消费者模板中使用#if (eq section 'header')
。【参考方案2】:
之前的回复可能已经过时了。
对于这个问题有一个公认的 RFC; Named Templates Block API 将支持将多个块传递给一个组件。
从 Ember 2.3 开始,Contextual components 允许使用另一种方法来处理这种情况:
将你的组件拆分成多个子组件,并将子组件作为块参数传回组件;此设置允许设置每个子组件块的内容。
查看Twiddle - full example。
// my-component.js
yield (hash
header = (component 'my-header')
content = (component 'my-content')
footer = (component 'my-footer')
)
#unless hasBlock
my-header
my-content
my-footer
/unless
// my-header/content/footer.js
#if hasBlock
yield
else
Default xxxxx
/if
在这种情况下,您可以使用默认组件内容或将特定内容传递给任何子组件,例如:
my-component
#my-component as |f|
f.header
#f.content
Custom content
/f.content
f.footer
/my-component
#my-component as |f|
#f.header
Custom header
/f.header
#f.content
Custom content
/f.content
#f.footer
Custom footer
/f.footer
/my-component
此解决方案不强制组件 API/结构,如果子组件被省略、多次添加或顺序错误,则组件可能会被错误地使用,在这些情况下组件会生成不需要的内容。
查看Twiddle - full example。
【讨论】:
这应该是 Ember 2.x 和 3.x 的公认答案 另外,父组件my-component
可以接受它们作为参数,而不是硬编码生成的子组件。以上是关于如何在 ember.js 组件模板中生成多条内容?的主要内容,如果未能解决你的问题,请参考以下文章
在 Angular 5 中生成新组件时缺少外部模板文件的原因是啥?