Swapping components

The dynamic composition docs suggest that the au-compose element is suitable for “Dynamically swap[ping] components based on user state or configuration” but the examples demonstrate doing this with literal values (strings, literal objects, template strings etc)

The scenario is a hierarchy where the different levels represent different types and a component is defined per type, for example folders and files. My hope was that I could just bind a different model to the same component if selecting another node of the same type but also swap out the component if selecting a node of a different type, something like this:

template.html

<au-compose component.bind="currentComponent" model.bind="currentModel"></au-compose>

template.ts

folderDetailComponent = new FolderDetailComponent();
fileDetailComponent = new FileDetailComponent();

treeview.on("itemClick", (itemClickEventArgs) => {
    console.log(itemClickEventArgs);
    switch (itemClickEventArgs.itemData.type) {
        case "Folder":
            this.currentComponent = this.folderDetailComponent;
            break;
        case "File":
            this.currentComponent = this.fileDetailComponent;
            break;
    }

    this.currentModel = itemClickEventArgs.itemData;
});

However this doesn’t seem to work. Is there something I’m missing about this approach or is there a more idiomatic solution?

Thanks

Your new FolderDetailComponent() is the culprit.

<au-compose> wants the component definition (constructor or element name), not an already‑constructed instance .

import { FolderDetailComponent } from './folder-detail';
import { FileDetailComponent }   from './file-detail';

componentMap = {
  Folder: FolderDetailComponent,
  File:   FileDetailComponent
};

currentComponent = FolderDetailComponent;   // default
currentModel     = undefined;               // will hold the clicked node

treeview.on('itemClick', e => {
  this.currentComponent = this.componentMap[e.itemData.type];
  this.currentModel     = e.itemData;       // triggers activate(model)
});
<au-compose
  component.bind="currentComponent"
  model.bind="currentModel">
</au-compose>
  • When you switch type, Aurelia disposes the old component and instantiates the new one.
  • When you only change model, the same component instance stays alive; its activate(model) hook fires with the new data.

Idiomatic extras:

  • Reuse the instance: if you truly need the same detail view to survive type changes, keep the component stable and drive everything through model; do the type check inside the component itself.
  • Lazy load big editors: set componentMap[type] = () => import(‘./folder-detail’).then(m => m.FolderDetailComponent) to pull code only when the user clicks.
  • Grab the child: component.ref=“detail” gives you a handle to call methods on the composed component if you need dirty‑form checks or focus tricks later.

Thanks for the clarification.