Как я могу предоставить несколько частей контента в шаблон компонента ember.js?
Цель состоит в том, чтобы определить структуру 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 принимает параметры. Однако рули еще не допускают встроенных сравнений переменных значений. Определив некоторые свойства на компоненте, мы можем приблизиться к тому, что делают рельсы.
В приведенном выше примере шаблон компонента будет выглядеть так:
<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}}
Ответ 2
Предыдущий ответ может быть устаревшим.
Существует принятый RFC для этой проблемы; API блоков именованных шаблонов будет поддерживать передачу нескольких блоков компоненту.
Начиная с версии 2.3, контекстуальные компоненты допускают другой подход к этому случаю:
Разделите ваш компонент на несколько подкомпонентов и передайте подкомпоненты обратно компоненту в качестве параметров блока; эта настройка позволяет установить содержимое каждого подкомпонентного блока.
Проверьте Twiddle - полный пример.
// 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 - полный пример.