From 8df8be58e1673024de9cd69a1f07ab2840a7f0f6 Mon Sep 17 00:00:00 2001 From: Richard Harris Date: Wed, 26 Jun 2019 21:21:22 -0400 Subject: [PATCH] ok NOW i think i have it --- .../render_dom/wrappers/shared/bind_this.ts | 43 +++++++++++++------ src/runtime/internal/scheduler.ts | 2 +- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/src/compiler/compile/render_dom/wrappers/shared/bind_this.ts b/src/compiler/compile/render_dom/wrappers/shared/bind_this.ts index f397a58e59..3d08cfaff5 100644 --- a/src/compiler/compile/render_dom/wrappers/shared/bind_this.ts +++ b/src/compiler/compile/render_dom/wrappers/shared/bind_this.ts @@ -31,31 +31,50 @@ export default function bind_this(component: Component, block: Block, binding: B const contextual_dependencies = Array.from(binding.expression.contextual_dependencies); - component.partly_hoisted.push(deindent` - function ${fn}(${['$$value', ...contextual_dependencies].join(', ')}) { - ${lhs} = $$value; - ${object && component.invalidate(object)} - } - `); - if (contextual_dependencies.length) { + component.partly_hoisted.push(deindent` + function ${fn}(${['$$value', ...contextual_dependencies].join(', ')}) { + if (${lhs} === $$value) return; + ${lhs} = $$value; + ${object && component.invalidate(object)} + } + `); + const args = []; for (const arg of contextual_dependencies) { args.push(arg); block.add_variable(arg, `ctx.${arg}`); } - const condition = Array.from(binding.expression.dependencies).map(name => `changed.${name}`).join(' || '); + const assign = block.get_unique_name(`assign_${variable}`); + const unassign = block.get_unique_name(`unassign_${variable}`); + + block.builders.init.add_block(deindent` + const ${assign} = () => ctx.${fn}(${[variable].concat(args).join(', ')}); + const ${unassign} = () => ctx.${fn}(${['null'].concat(args).join(', ')}); + `); + + const condition = Array.from(contextual_dependencies).map(name => `${name} !== ctx.${name}`).join(' || '); block.builders.update.add_line(deindent` if (${condition}) { - ctx.${fn}(${['null'].concat(args).join(', ')}); + ${unassign}(); ${args.map(a => `${a} = ctx.${a}`).join(', ')}; - @add_binding_callback(() => ctx.${fn}(${[variable].concat(args).join(', ')})); + @add_binding_callback(${assign}); }` ); + + block.builders.destroy.add_line(`${unassign}();`); + return `@add_binding_callback(${assign});`; } - block.builders.destroy.add_line(`ctx.${fn}(${['null', ...contextual_dependencies.map(name => `ctx.${name}`)].join(', ')});`); - return `@add_binding_callback(() => ctx.${fn}(${[variable, ...contextual_dependencies.map(name => `ctx.${name}`)].join(', ')}));`; + component.partly_hoisted.push(deindent` + function ${fn}($$value) { + ${lhs} = $$value; + ${object && component.invalidate(object)} + } + `); + + block.builders.destroy.add_line(`ctx.${fn}(null);`); + return `@add_binding_callback(() => ctx.${fn}(${variable}));`; } \ No newline at end of file diff --git a/src/runtime/internal/scheduler.ts b/src/runtime/internal/scheduler.ts index a26a4f8c33..9e1b4280bf 100644 --- a/src/runtime/internal/scheduler.ts +++ b/src/runtime/internal/scheduler.ts @@ -46,7 +46,7 @@ export function flush() { update(component.$$); } - while (binding_callbacks.length) binding_callbacks.shift()(); + while (binding_callbacks.length) binding_callbacks.pop()(); // then, once components are updated, call // afterUpdate functions. This may cause