mirror of https://github.com/sveltejs/svelte
fix: make `bind_this` implementation more robust (#10598)
The previous `bind_this` implementation had flaws around timing and didn't work correctly when the binding wasn't `$state` in runes mode. This PR reimplements `bind_this` by aligning it more with how Svelte 4 bindings work, namely reacting to each block context variables updates properly and introducing a mechanism to get the previous binding destination using said variables.pull/10605/head
parent
d2b11ec4da
commit
a2164ff9f4
@ -0,0 +1,5 @@
|
||||
---
|
||||
"svelte": patch
|
||||
---
|
||||
|
||||
fix: make `bind_this` implementation more robust
|
@ -0,0 +1,43 @@
|
||||
import { tick } from 'svelte';
|
||||
import { test } from '../../test';
|
||||
|
||||
/** @param {number | null} selected */
|
||||
function get_html(selected) {
|
||||
return `
|
||||
<button>1</button>
|
||||
<button>2</button>
|
||||
<button>3</button>
|
||||
|
||||
<hr></hr>
|
||||
|
||||
${selected !== null ? `<div>${selected}</div>` : ''}
|
||||
|
||||
<hr></hr>
|
||||
|
||||
<p>${selected ?? '...'}</p>
|
||||
`;
|
||||
}
|
||||
|
||||
export default test({
|
||||
html: get_html(null),
|
||||
|
||||
async test({ assert, target }) {
|
||||
const [btn1, btn2, btn3] = target.querySelectorAll('button');
|
||||
|
||||
await btn1?.click();
|
||||
await tick();
|
||||
assert.htmlEqual(target.innerHTML, get_html(1));
|
||||
|
||||
await btn2?.click();
|
||||
await tick();
|
||||
assert.htmlEqual(target.innerHTML, get_html(2));
|
||||
|
||||
await btn1?.click();
|
||||
await tick();
|
||||
assert.htmlEqual(target.innerHTML, get_html(1));
|
||||
|
||||
await btn3?.click();
|
||||
await tick();
|
||||
assert.htmlEqual(target.innerHTML, get_html(3));
|
||||
}
|
||||
});
|
@ -0,0 +1,30 @@
|
||||
<script>
|
||||
import { tick } from 'svelte';
|
||||
|
||||
let selected = $state(-1);
|
||||
let current = $state();
|
||||
|
||||
let div; // explicitly no $state
|
||||
</script>
|
||||
|
||||
{#each [1, 2, 3] as n, i}
|
||||
<button
|
||||
onclick={async () => {
|
||||
selected = i;
|
||||
await tick();
|
||||
current = div?.textContent;
|
||||
}}
|
||||
>{n}</button>
|
||||
{/each}
|
||||
|
||||
<hr />
|
||||
|
||||
{#each [1, 2, 3] as n, i}
|
||||
{#if selected === i}
|
||||
<div bind:this={div}>{n}</div>
|
||||
{/if}
|
||||
{/each}
|
||||
|
||||
<hr />
|
||||
|
||||
<p>{current ?? '...'}</p>
|
Loading…
Reference in new issue