简体   繁体   中英

Passing mutilple HTML fragments / other components to a component

Consider a simple component in Aurelia:

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

And the corresponding HTML template:

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

As simple as it gets. Now I can use this component in a parent like this:

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

Question 1

What if I don't want to provide the child component just with simple strings, but instead I want to set them with HTML fragments?

Question 2

What if the I want to pass whole complete components as in str1 and str2 ?

Here's a gist demo: https://gist.run/?id=0bf83980935015217cfb83250643c13f

Content Projection

It applies for Question 1 and Question 2 .

[Documentation] By using slots, you can define the content of your custom component declaratively. It can contain other custom components as well.

frame-slot.html

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

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

usage in 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>

Inline ViewStrategy

It applies for Question 1 and Question 2 .

[Documentation] By using InlineViewStrategy, you can define templates as plain string variables and display it with the help of <compose> element [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>';
}

usage in app.html

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

InnerHTML binding

It applies for Question 1 only.

You can bind content to an element's innerHTML property. I'm mentioning that, but you should use it with caution or not at all.

[Documentation]

Binding using the innerhtml attribute simply sets the element's innerHTML property. The markup does not pass through Aurelia's templating system. Binding expressions and require elements will not be evaluated.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM