Does Aurelia support transclusion?
Asked Answered
M

3

7

I'm familiar with the concept of ngTransclude via AngularJS and this.props.children via ReactJs, however does Aurelia support transclusion, that is, the notion of inserting, or transcluding, arbitrary content into another component?


Transclusion in AngularJS (https://plnkr.co/edit/i3STs2MjPrLhIDL5eANg)

HTML

<some-component>
  Hello world
</some-component>

JS

app.directive('someComponent', function() {
  return {
    restrict: 'E',
    transclude: true,
    template: `<div style="border: 1px solid red">
                  <div ng-transclude>
               </div>`
  }
})

RESULT

result


Transclusion in ReactJs (https://plnkr.co/edit/wDHkvVJR3FL09xvnCeHE)

JS

const Main = (props) => (
    <SomeComonent>
      hello world
    </SomeComonent>
);

const SomeComonent = ({children}) => (
    <div style={{border: '1px solid red'}}> 
      {children}
    </div>
);

RESULT

result

Mateusz answered 14/1, 2016 at 22:9 Comment(0)
E
11

Several ways to do transclusion: Official docs

1. content slot <slot></slot>

The <slot> element serves as a placeholder in a component's template for arbitrary content. Example:

some-component.html

<template>
  <div style="border: 1px solid red">
    <slot></slot>
  </div>
</template>

usage:

<template>
  <require from="some-component"></require>

  <some-component>
    hello world
  </some-component>
</template>

result:
result

2. named slots

A component can contain several replaceable parts. The user of the component can replace some or all of the parts. Parts that aren't replaced will display their default content.

blog-post.html

<template>
  <h1>
    <slot name="header">
      Default Title
    </slot>
  </h1>
  <article>
    <slot name="content">
      Default content
    </slot>
  </article>
  <div class="footer">
    <slot name="footer">
      Default footer
    </slot> 
  </div>
</template>

usage:

<template>
  <require from="blog-post"></require>

  <blog-post>
    <template slot="header">
      My custom header
    </template>
    <template slot="content">
      My custom content lorem ipsum fla fla fla
    </template>
    <template slot="footer">
      Copyright Megacorp
    </template> 
  </blog-post>
</template>

3. template parts

The slots spec has limitations: http://aurelia.io/hub.html#/doc/article/aurelia/templating/latest/templating-content-projection/5

Use template-parts for dynamically generated slots: https://github.com/aurelia/templating/issues/432

Enchilada answered 17/1, 2016 at 20:14 Comment(3)
Trap for young players: you can't use <content> to fill in <option>s in a <select> - see github.com/aurelia/framework/issues/304 - this had me stumped for quite a while before I opened that issue and Rob cleared it up for me.Connally
This answer seems to be outdated, according to the docs you should use <slot></slot> instead of <content></content>Dufrene
It looks like <template slot="slot-name">Content</template> is not working, instead you should use a div or something. It's also described in the Aurelia docs that way.Dufrene
M
2

Yes, Aurelia supports the concept of transclusion through use of the <content /> component. Per the below, any content nested within <some-component> be it HTML, a String, or another component, will be rendered within this component.

app.js

export class App {}

app.html

<template>
  <require from="some-component"></require>
  <some-component>
    hello world
  </some-component>
</template>

some-component.js

export class SomeComponent {}

some-component.html

<template>
  <div style="border: 1px solid red">
    <content />
  </div>
</template>

RESULT

result

Mateusz answered 14/1, 2016 at 22:9 Comment(0)
D
1

UPDATE: USE SLOT INSTEAD OF CONTENT

// Actual component
<your-component>
  Just some content
</your-component>

// Template of the component
<template>
  <div class="some-styling">
    <slot></slot> // <-- "Just some content" will be here!!
  </div>
</template>
Dufrene answered 1/5, 2017 at 18:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.