Well i see that your solution works, I’m not sure why it works. I also tried a similar approach on my end and I still cannot get attached to fire. I’m trying to keep the usage of this to only requiring the <component-renderer view-model.bind="itemTemplateViewModel" model.bind="model"> </component-renderer>
This is very useful in a custom listbox I built that accepts a view/viewModel as the template.
If I use the compose tag passing in the path to the viewModel, all works as expected. Pretty much all I’m trying to do is build another version of the compose tag that accept a function instead of the module path. I’m really confused why all rendering is okay, but the activate method is not being called
View TestPage
<template>
<component-renderer view-model.bind="itemTemplateViewModel" model.bind="model">
</component-renderer>
</template>
ViewModel: TestPage
import { ListBoxItemViewModel } from "listboxItemViewModel";
export class ListboxTest {
itemTemplateViewModel = ListBoxItemViewModel;
model = { text: "Item 1", canClick: false };
}
ViewModel: ComponentRenderer
import { bindable, autoinject, CompositionEngine, CompositionContext, Container, ViewSlot } from "aurelia-framework";
@autoinject
export class ComponentRenderer {
@bindable
public model: any = null;
@bindable
public viewModel: any = null;
rendererContainer: HTMLDivElement = null;
constructor(private compositionEngine: CompositionEngine, private container: Container) {
}
createContext(viewModel: object, host: Element, model: object): CompositionContext {
return {
container: this.container.createChild(),
viewModel: viewModel,
model: model,
host: host,
bindingContext: null,
viewResources: null,
viewSlot: new ViewSlot(host, true)
};
}
attached() {
console.log("component rendered attached");
if (this.rendererContainer !== null) {
let context = this.createContext(new this.viewModel(), this.rendererContainer, this.model);
this.compositionEngine.compose(context).then((view: any) => {
console.log("rendered")
});
}
}
detached() {
this.rendererContainer = null;
this.viewModel = null;
this.model = null;
}
}
View: ComponentRenderer
<template>
<div element.ref="rendererContainer">
</div>
</template>
ViewModel: ListBoxItemViewModel
export class LisboxItemViewModelBase {
public item: any = null;
activate(model) {
this.item = model;
console.log("LisboxItemViewModelBase activate");
}
attached() {
console.log("item template attached");
}
}
export class ListBoxItemViewModel extends LisboxItemViewModelBase {
attached() {
console.log("item template attached");
}
}
View: ListBoxItemViewModel
<template>
${item.text}
</template>