The problem is that you are pushing items inside the attached
method and you are using dynamic composition, which usually is not a problem but your situation is a bit different. Queuing a micro-task doesn't help because it runs before your view (child.html) is loaded.
There are couple ways to solve the this problem:
1° Solution
Push your items inside bind()
:
bind() {
this.items.push({
view: 'child.html',
viewModel: new Child('A')
});
this.items.push({
view: 'child.html',
viewModel: new Child('B')
});
}
attached() {
let container = document.getElementById('container');
console.log('Height after adding items: ' + container.clientHeight);
this._taskQueue.queueMicroTask(() => {
console.log('Height after queued microtask: ' + container.clientHeight);
});
setTimeout(() => {
console.log('Height after waiting a second: ' + container.clientHeight);
}, 1000);
}
Fix the HTML:
<template>
<div id="container">
<div repeat.for="item of items">
<compose view-model.bind="item.viewModel" view.bind="item.view"></compose>
</div>
</div>
<div style='margin-top: 20px'>
<div repeat.for="log of logs">
${log}
</div>
</div>
</template>
Running example https://gist.run/?id=7f420ed45142908ca5713294836b2d5e
2º Solution
Do not use <compose>
. Compose was made to be used when dynamic compositions are necessary. Are you sure you need to use <compose>
?.
<template>
<require from="./child"></require>
<div id="container">
<div repeat.for="item of items">
<child>${item.data}</child>
</div>
</div>
</template>