目标是定义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中使用?
答案 0 :(得分:18)
从ember v1.10开始,yield接受参数。但是,把手还不允许对变量值进行内联比较。通过在组件上定义一些属性,我们可以非常接近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}}
答案 1 :(得分:4)
上一个回复可能是最新的。
有一个公认的RFC,可以解决此问题; Named Templates Block API将支持将多个块传递到组件。
从Ember 2.3开始, Contextual components 允许使用另一种方法来解决这种情况:
将您的组件拆分为多个子组件,并将这些子组件作为块参数传递回该组件;此设置允许设置每个子组件块的内容。
// 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 /结构,因此,如果子组件被省略,多次添加或顺序错误,则可能会错误地使用该组件,在这种情况下,该组件将生成不需要的内容。