如何在 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 headerMy bodyMy 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 中生成新组件时缺少外部模板文件的原因是啥?

如何在 Chrome 中自动播放 ember.js 中的视频

如何在 Ember.js 中获取复选框状态?

如何在 Django 模板中生成换行符

如何在ember js中从子组件调用父组件方法

使用 Ember.js 按模型类型/对象值选择视图模板