0

I'm trying to implement a 'switcher' or 'viewstack' component in Aurelia, this would be useful for wizards, paged content, and stepping through a list of tasks. This would show a single child component at a time from a number of possible children. I'd like the usage markup to resemble:

<my-switcher>
    <one-component></one-component>
    <two-component></two-component>
    <three-component></three-component>
</my-switcher>

Now, the obvious alternatives here are:

  1. <compose view-model.bind="currentStep"> and point the currentStep variable to each component at a time. (+ves: components are only instantiated when accessed, -ves: needing to know the path for each component, all children need to be valid view-models)
  2. Add an if.bind='active' within the definition of each component in the slot, and just set this active member from the my-switcher class. (+ves: easier to follow, -ves: components need to be specifically written for use here).
  3. Retrieve the children via @children (if this now works reliably?) and add the Element as a child DOM element manually, then call ViewCompiler.enhance. (-ves: can't seem to get get @children to work, larger amount of custom code)

Each of these feels a bit contrived a solution. Does anyone have any idea about whether there a cleaner approach that could/should be used instead?

Rich Barber
  • 425
  • 3
  • 11

1 Answers1

1

Combine options 2 and 3 while avoiding the negatives (not sure why you can't get @children to work).

consumer.html

<my-switcher>
    <my-switcher-item>
        <one-component></one-component>
    </my-switcher-item>
    <my-switcher-item>
        <two-component></two-component>
    </my-switcher-item>
    <my-switcher-item>
        <three-component></three-component>
    </my-switcher-item>
</my-switcher>

my-switcher-item.js

export class MySwitcherItem {
    constructor() {
        this.isActive = false;
    }
}

my-switcher-item.html

<template show.bind="isActive">
    <slot></slot>
</template>

my-switcher.js

import {children} from 'aurelia-framework';

export class MySwitcher {
    @children('my-switcher-item') items = [];

    // Here you have access to this.items[index].isActive.

    // You can set this value to true or false from this class
    // and make sure only one item's isActive is true.

    // You could add next() and previous() methods to move between
    // the items, etc.
}
Jeff G
  • 1,996
  • 1
  • 13
  • 22
  • If you're not happy about consumers having to add the elements, you could simply add them automatically in a @processContent function in the MySwitcher class. – Jeff G Dec 04 '16 at 16:30