contextual bind:this

pull/1927/head
Richard Harris 7 years ago
parent ff2a21e63a
commit 4e1eb54cce

@ -282,11 +282,6 @@ export default class ElementWrapper extends Wrapper {
});
}
const eventHandlerOrBindingUsesComponent = (
this.bindings.length > 0 ||
this.node.handlers.some(handler => handler.usesComponent)
);
const eventHandlerOrBindingUsesContext = (
this.bindings.some(binding => binding.node.usesContext) ||
this.node.handlers.some(handler => handler.usesContext) ||
@ -534,17 +529,46 @@ export default class ElementWrapper extends Wrapper {
renderer.component.declarations.push(name);
renderer.component.template_references.add(name);
const { handler, object } = this_binding.munge(block);
const munged = this_binding.munge(block);
const { handler, object } = munged;
renderer.component.partly_hoisted.push(deindent`
function ${name}($$node) {
${handler.mutation}
$$invalidate('${object}', ${object});
}
`);
// TODO this really is spectacularly confusing,
// the whole mess needs cleaning up
const contextual_dependencies = new Set();
addToSet(contextual_dependencies, munged.contextual_dependencies);
addToSet(contextual_dependencies, handler.contextual_dependencies);
let fn;
if (contextual_dependencies.size > 0) {
block.builders.init.addBlock(deindent`
function ${name}() {
ctx.${name}(${this.var}, ctx);
}
`);
fn = deindent`
function ${name}($$node, { ${[...contextual_dependencies].join(', ')} }) {
${handler.mutation}
$$invalidate('${object}', ${object});
}
`;
block.builders.mount.addLine(`@add_binding_callback(${name});`);
block.builders.destroy.addLine(`ctx.${name}(null, ctx);`);
} else {
fn = deindent`
function ${name}($$node) {
${handler.mutation}
$$invalidate('${object}', ${object});
}
`;
block.builders.mount.addLine(`@add_binding_callback(() => ctx.${name}(${this.var}));`);
block.builders.destroy.addLine(`ctx.${name}(null);`);
}
block.builders.mount.addLine(`@add_binding_callback(() => ctx.${name}(${this.var}));`);
block.builders.destroy.addLine(`ctx.${name}(null);`);
renderer.component.partly_hoisted.push(fn);
}
}

@ -0,0 +1,42 @@
export default {
props: {
items: ['a', 'b', 'c']
},
html: `
<div>a</div>
<div>b</div>
<div>c</div>
`,
test({ assert, component, target }) {
let nodes = [...target.querySelectorAll('div')];
assert.deepEqual(component.nodes, nodes);
console.group('setting b, c, d, e');
component.items = ['b', 'c', 'd', 'e'];
console.groupEnd();
assert.htmlEqual(target.innerHTML, `
<div>b</div>
<div>c</div>
<div>d</div>
<div>e</div>
`);
nodes = [...target.querySelectorAll('div')];
assert.deepEqual(component.nodes, nodes);
console.group('setting c, d');
component.items = ['c', 'd'];
console.groupEnd();
assert.htmlEqual(target.innerHTML, `
<div>c</div>
<div>d</div>
`);
nodes = [...target.querySelectorAll('div')];
assert.deepEqual(component.nodes, [...nodes, null, null]);
}
};

@ -0,0 +1,8 @@
<script>
export let items;
export let nodes = [];
</script>
{#each items as item, i (item)}
<div bind:this={nodes[i]}>{item}</div>
{/each}
Loading…
Cancel
Save