Mehran
Mehran

Reputation: 16931

Providing the model for a component as a slot

Consider the following two custom elements in Aurelia (list & row):

row.html

<template>
  <span>${name}</span>
</template>

row.js

export class Row
{
  name = "Marry";
}

list.html

<template>
  The List
  <ol>
    <li repeat.for="r of rows">
      <slot name="rowItem" model.bind="r"></slot>
    </li>
  </ol>
</template>

list.js

import { bindable } from 'aurelia-framework';

export class List
{
    @bindable
    rows = [{name: "John"}];
}

The app will tie them together:

app.html

<template>
  <require from="./list"></require>
  <require from="./row"></require>

  <list rows.bind="users">
    <row slot="rowItem"></row>
  </list>
</template>

app.js

export class App
{
  users = [{name: "Joe"}, {name: "Jack"}, {name: "Jill"}];
}

The problem is that the model for the row is not set correctly. All I get as the output is the following:

The List
  1.
  2.
  3.

So the question is; how can I provide the model for a slot in Aurelia?

Here's a Gist to demonstrate the problem in action.

Upvotes: 3

Views: 317

Answers (1)

Ashley Grant
Ashley Grant

Reputation: 10897

Slots aren't going to work for what you want to do. It's a known limitation of slots in Aurelia. Slots can't be dynamically generated (such as inside a repeater).

Luckily, there's another option to accomplish what you want: template parts.

Template parts aren't well documented (my fault, I should have written the docs for them). But we have some docs in our cheat sheet. I've modified your gist to show how to use them: https://gist.run/?id=1c4c93f0d472729490e2934b06e14b50

Basically, you'll have a template element in your custom element's HTML that has the replaceable attribute on it along with a part="something" attribute (where something is replaced with the template part's name. Then, when you use the custom element, you'll have another template element that has the replace-part="something" attribute (again, where something is replaced with the template part's name). It looks like this:

list.html

<template>
  The List
  <ol>
    <li repeat.for="row of rows">
      <template replaceable part="row-template">
        ${row}
      </template>
    </li>
  </ol>
</template>

app.html

<template>
  <require from="./list"></require>
  <require from="./row"></require>

  <list rows.bind="users">
    <template replace-part="row-template">
      <row name.bind="row.name"></row>
    </template>
  </list>
</template>

Upvotes: 5

Related Questions