Передача поврежденных фрагментов HTML / других компонентов компоненту

#aurelia

#aurelia

Вопрос:

Рассмотрим простой компонент в Aurelia:

 export class FrameComponent
{
    @bindable str1;
    @bindable str2;
}
  

И соответствующий HTML-шаблон:

 <template>
    ${str1}
    ${str2}
</template>
  

Настолько просто, насколько это возможно. Теперь я могу использовать этот компонент в родительском элементе следующим образом:

 <template>
    <require from="./frame-component"></require>
    <frame-component str1="Hello" str2="World"></frame-component>
</template>
  

Вопрос 1

Что, если я не хочу предоставлять дочернему компоненту только простые строки, а вместо этого хочу установить их с помощью фрагментов HTML?

Вопрос 2

Что, если я хочу передать целые полные компоненты, как в str1 и str2 ?

Ответ №1:

Вот демонстрация сути: https://gist.run/?id=0bf83980935015217cfb83250643c13f

Проекция содержимого

Это относится к вопросу 1 и вопросу 2.

[Документация] С помощью слотов вы можете декларативно определять содержимое вашего пользовательского компонента. Он также может содержать другие пользовательские компоненты.

frame-slot.html

 <template>
  <div>
    <slot name="str1">Default str1</slot>
  </div>

  <div>
    <slot name="str2">Default str2</slot>
  </div>
</template>
  

использование в app.html

 <require from="./frame-slot"></require>

<frame-slot>
    <div slot="str1"><h3>${slotStr1}</h3></div>
    <div slot="str2">
        <h3>${slotStr2}</h3>
        <div>
            <frame-slot></frame-slot>
        </div>
    </div>
</frame-slot>
  

Встроенная стратегия просмотра

Это относится к вопросу 1 и вопросу 2.

[Документация] Используя InlineViewStrategy, вы можете определять шаблоны как простые строковые переменные и отображать их с помощью <compose> элемента [Composition docs].

frame-inline.js

 import { bindable, InlineViewStrategy } from 'aurelia-framework';

export class FrameInline {
  @bindable template;
  @bindable model;

  viewStrategy;

  attached() {
    this.viewStrategy = new InlineViewStrategy(`<template>${this.template}</template>`);
  }
}
  

frame-inline.html

 <template>
  <compose view.bind="viewStrategy" model.bind="model"></compose>
</template>
  

app.js

 export class App {

  inlineModel = { 
    name: "inline-template",
    description: "This is an inline template",
    slot: "Frame-slot Str1 content within frame-inline"
  };

  inlineTemplate = '<require from="./frame-slot"></require>'   
                   '<div>${model.name}: ${model.description}</div>'   
                   '<br>'  
                   '<frame-slot>'   
                     '<div slot="str1">${model.slot}</div>'  
                   '</frame-slot>';
}
  

использование в app.html

 <require from="./frame-inline"></require>
<frame-inline template.bind="inlineTemplate" model.bind="inlineModel"></frame-inline>
  

Привязка к innerHTML

Это относится только к вопросу 1.

Вы можете привязать содержимое к свойству innerHTML элемента. Я упоминаю об этом, но вы должны использовать его с осторожностью или вообще не использовать.

[Документация]

Привязка с использованием атрибута innerhtml просто устанавливает свойство innerHTML элемента. Разметка не проходит через систему шаблонов Aurelia. Выражения привязки и элементы require оцениваться не будут.

 <div innerHTML.bind="content | sanitizeHTML"></div>
  

Комментарии:

1. Потрясающий ответ!