-
Notifications
You must be signed in to change notification settings - Fork 48
Open
Description
The bellow is a simple example of how i would expect (?) nested signals to work.
When clicking "to cart" it should change to "loading".
<html>
<body>
<div id="products"></div>
<script type="module">
import {render, signal, html, effect, computed} from 'https://esm.run/uhtml/signal';
class Cart {
add(product) {
console.log('adding to cart: ', product.name);
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('added to cart: ', product.name);
resolve();
}, 2000);
})
}
}
const cart = new Cart();
class Item {
constructor(sData) {
this.data = sData;
}
renderItem() {
return html`
<li>${this.data.value.name}
<button @click="${e => {
this.data.value.loading_cart = true
cart.add(this.data.value).then(() => {
this.data.value.loading_cart = false
});
}}">${this.data.value.loading ? 'loading' : 'to cart'}
</button>
</li>`;
}
}
class Catalog {
#items = signal([]);
#computed;
#effect;
constructor() {
this.#computed = computed(() => this.#items.value.map(item => (new Item(signal(item))).renderItem()));
this.#effect = effect(() => {
render(document.getElementById('products'), () => html`
<ul>${this.#computed.value}</ul>`)
});
}
addItem(value) {
this.#items.value = [...this.#items.value, value];
}
setItems(items) {
this.#items.value = items;
}
}
const catalog = new Catalog();
setTimeout(() => {
catalog.setItems([
{name: 'Shoes'},
{name: 'T-Shirt'}
])
setTimeout(() => {
catalog.addItem({name: 'Hat'})
catalog.addItem({name: 'Boots'})
}, 1500)
}, 500)
</script>
</body>
</html>
What would be a working example for the above?
Metadata
Metadata
Assignees
Labels
No labels