En En

Упаковка контента в компонент


Иногда вам будет нужно определить компонент, который охватывает контент, предоставленный другими шаблонами.

Представьте, что вы создаете компонент blog-post, который можно использовать в приложении для отображения публикации блога:

app/templates/components/blog-post.hbs

<h1>{{title}}</h1>
<div class="body">{{body}}</div>

Теперь мы можем использовать компонент {{blog-post}} и передавать ему свойства в другом шаблоне:

{{blog-post title=title body=body}}

(Смотрите раздел «Передача свойств компоненту»).

В этом случае нужный нам контент мы получили из модели. Но что если мы хотим, чтобы разработчик, использующий наш компонент, мог предоставить свой HTML-контент?

В дополнение к простой форме, которую мы уже изучили, компоненты могут использоваться в блочной форме. В этой форме компоненты можно передавать в шаблон Handlebars и отображать контент внутри шаблона компонента, где появляется выражение {{yield}}.

Чтобы использовать блочную форму, поставьте знак # в начало имени компонента и добавьте закрывающий тег. (Смотрите документацию Handlebars по блочным выражениям).

В этом случае мы можем использовать компонент {{blog-post}} в блочной форме и с помощью хелпера {{yield}} указать Ember, где следует отобразить блочный контент. Чтобы обновить пример выше, мы сначала изменим шаблон компонента:

app/templates/components/blog-post.hbs

<h1>{{title}}</h1>
<div class="body">{{yield}}</div>

Как видите, мы заменили {{body}} на {{yield}}. Так Ember понимает, что этот контент будет предоставлен при использовании компонента.

Далее, мы обновим шаблон с компонентом, чтобы использовать блочную форму:

app/templates/index.hbs

{{#blog-post title=title}}
  <p class="author">by {{author}}</p>
  {{body}}
{{/blog-post}}

Важно отметить, что область действия шаблона внутри компонентного блока такая же, как снаружи. Если свойство доступно в шаблоне вне компонента, оно будет доступно и внутри компонентного блока.

Обмен данными компонента с заключенным в него контентом

Существует способ обмениваться данными внутри вашего компонента blog post с заключенным в него контентом. Нам нужно, чтобы компонент blog post позволял настраивать стиль, который пользователь хочет использовать для написания публикаций. Мы предоставим выбор между markdown и html.

app/templates/index.hbs

{{#blog-post editStyle="markdown"}}
  <p class="author">by {{author}}</p>
  {{body}}
{{/blog-post}}

Поддержка разных стилей редактирования потребует различных компонентов body для предоставления специальной проверки соответствия и выделения. Чтобы загрузить компонент body на основе стиля редактирования, можно создать компонент с помощью хелперов component и hash.

app/templates/components/blog-post.hbs

<h2>{{title}}</h2>
<div class="body">{{yield (hash body=(component editStyle))}}</div>

После создания данных можно получить к ним доступ внутри заключенного в компонент контента путем обращения с переменной as.

app/templates/index.hbs

{{#blog-post editStyle="markdown" as |post|}}
  <p class="author">by {{author}}</p>
  {{post.body}}
{{/blog-post}}

Наконец, нам нужно поделиться моделью данных, которую пользователь оформил для публикации, внутри наших компонентов blog-post и body. Чтобы поделиться объектом postData с новым компонентом body, можно добавить аргументы хелперу component.

app/templates/components/blog-post.hbs

<h2>{{title}}</h2>
<div class="body">{{yield (hash body=(component editStyle postData=postData))}}</div>

Так как компонент не будет инстанцирован, пока не отобразится блочный контент компонента, можно добавлять аргументы внутри блока. В этом случае мы добавим вариант текстового стиля, который будет определять стиль основного текста в нашей публикации. Когда {{post.body}} инстанцирован, у него будет стиль редактирования и объект postData, заданные компонентом, в котором он заключен.

app/templates/index.hbs

{{#blog-post editStyle="markdown" as |post|}}
  <p class="author">by {{author}}</p>
  {{post.body editStyle="compact"}}
{{/blog-post}}

Компоненты, где используется такой обмен данными, обычно называют «контекстуальными», потому что данные компонента передаются только с контекстом блочной области родительского компонента.


Комментарии (0)

    Выделите опечатку и нажмите Ctrl + Enter, чтобы отправить сообщение об ошибке.