-
-
Notifications
You must be signed in to change notification settings - Fork 4.7k
Open
Description
Describe the problem
I am trying to emulate Svelte 4's binding behavior with Svelte 5. Both of the following work but are clumsy:
<script>
let x = $state({ a: 1, b: 2 });
// Define the lens function
function lens(obj, key) {
return {
get value() {
return obj[key];
},
set value(v) {
obj[key] = v;
}
};
}
// Create the lens
let aLens = lens(x, "a");
</script>
<input bind:value={aLens.value} />
<p>State: {x.a}</p> <!-- Updates automatically -->
<p>Lens: {aLens.value}</p> <!-- Updates automatically --><script>
let x = $state({ a: 1, b: 2 });
function lens(obj, key) {
return [
() => obj[key], // getter
(v) => obj[key] = v // setter
];
}
let [aGet, aSet] = lens(x, "a");
</script>
<input bind:value={aGet, aSet} />
<p>State: {x.a}</p> <!-- Updates automatically -->
<p>Lens: {aGet()}</p> <!-- Updates automatically -->The former requires me to type .value everywhere, and the latter requires me to type .get, .set everywhere.
Describe the proposed solution
Can the function binding syntax directly support an array or object with a getter and setter? Then we could just use bind:value={aLens}
Further, it would be nice if we could use directly use such a getter, setter combination as a value. That is, <p>The value is: {aLens} </p>
Another possibility is to use a store. It works, but I am not entirely sure if it's completely valid (generated by AI):
<script>
let x = $state({ a: 1, b: 2 });
function lens(obj, key) {
return {
subscribe: (run) => {
const cleanup = $effect.root(() => {
$effect(() => {
run(obj[key]);
});
});
return cleanup;
},
set: (value) => {
obj[key] = value;
}
};
}
let aLens = lens(x, "a");
</script>
<input type="number" bind:value={$aLens} />
<p>State: {x.a}</p>
<p>Lens: {$aLens}</p>Importance
i cannot use svelte without it
Metadata
Metadata
Assignees
Labels
No labels