有时你可能希望定义一个包装由其他模板提供的内容的组件。
例如,想象我们创建一个组件,名字叫blog-post
,我们可以用它来展示我们应用程序中的 博客文章。
//in component.hbs
<h1>{{title}}</h1>
<div class='body'>{{body}}</div>
现在,我们可以使用这个blog-post
组件并在其他模板中传递属性:
{{blog-post title=title body=body}}
查看 Passing Properties to a Component获取更多内容。
在这个例子中,我们想要展示的内容来自model。但是如果我们希望使用我们组件的开发人员能够提供自定义HTML的内容呢?
除了你目前已经学过的简单的形式,组件还支持使用块级形式。在块级形式中,组件可以传递Handlebars模板,该模板在组件模板中{{yield}}表达式出现的任何地方呈现。
要使用块级形式,在组件名字的开头加一个#
字符,然后确保添加了闭合标签。
查看block expressions上的Handlebars文件获取更多信息。
在这个例子中,我们可以使用块级形式的{{blog-post}}
组件,并且告诉Ember在哪使用{{yield}}帮助器使块级内容被渲染出来。为了更新上面的例子,我们首先更改组件的模板:
//in component.hbs
<h1>{{title}}</h1>
<div class='body'>{{yield}}<div>
你可以看到我们把{{body}}替换成了{{yield}}.这告诉Ember当组件被使用时这块内容会被提供。
下一步,我们将使用这个组件来更新模板以使用块级形式:
//in index.hbs
{{#blog-post title=title}}
<p class='author'>by {{author}}</p>
{{body}}
</blog-post>
注意组件内的模板范围与外部相同。如果一个属性在组件外部的模板中是可用的,那么它在组件块的内部也是可用的。
和包裹内容共享组件数据
还有一种方法可以将博客文章组件中的数据与其包装的内容进行共享。在我们的博客文章组件中我们希望给用户提供一种方法来配置他们想要在其中撰写文章的样式。我们将为他们提供指定markdown-style
或html-style
的选项。
//in index.hbs
{{#blog-post editStyle="markdown-style"}}
<p class='author'>by {{author}}</p>
{{body}}
{{/blog-post}}
支持不通的编辑样式将请求不同的主体组件来提供特殊验证和高亮显示。为了根据编辑样式加载不同的主体组件,你可以使用 component helper
和hash helper
生成组件。在这里,使用嵌套的helper将适当的组件分配给哈希并将其输出到模板。注意editStyle
是被用作组件助手的参数。
//in component.hbs
<h2>{{title}}</h2>
<div class='body'>
{{yield (hash body=(component editStyle))}}
</div>
一旦产生,通过引用post
变量,包装内容可以引用数据。现在一个叫做markdown-style
的组件将会在{{post.body}}中呈现。
//in index.hbs
{{#blog-post editStyle="markdown-style" postData=myText as |post|}}
<p class='anthor'>by {{author}}</p>
{{post.body}}
</blog-post>
最后,我们需要与body
共享myText
才能显示它。要将博客文本传递给body
组件,我们将向组件助手添加postData
参数。
//in component.hbs
<h2>{{title}}</h2>
<div class="body">
{{yield (hash body=(component editStyle postData=postData))}}
</div>
此时,我们的块内容可以通过包装blog-post
组件的模板助手访问它需要呈现的所有内容。
此外,由于在呈现块内容之前不会实例化组件,我们可以在块中添加参数。在这种情况下,我们将添加一个文本样式选项,它将指示我们在文章中想要的正文文本的样式。当{{post.body}}
被实例化时,它将包含由其包装组件给出的editStyle
和postData
,以及在模板中声明的bodyStyle
。
// in index.hbs
{{#blog-post editStyle="markdown-style" postData=myText as |post|}}
<p class="author">by {{author}}</p>
{{post.body bodyStyle="compact-style"}}
{{/blog-post}}
以这种方式构建的组件通常被称为上下文组件,允许内部组件在外部组件的上下文中包装而不破坏封装。
网友评论