pull/17038/head
Rich Harris 3 weeks ago
parent 80d7bfd15e
commit f85aff43c8

@ -172,6 +172,7 @@ export function BindDirective(node, context) {
}
const binding = context.state.scope.get(left.name);
node.metadata.binding = binding;
if (assignee.type === 'Identifier') {
// reassignment

@ -243,18 +243,29 @@ export function BindDirective(node, context) {
}
}
const defer =
node.name !== 'this' &&
parent.type === 'RegularElement' &&
parent.attributes.find((a) => a.type === 'UseDirective');
let statement = defer ? b.stmt(b.call('$.effect', b.thunk(call))) : b.stmt(call);
// TODO this doesn't account for function bindings
if (node.metadata.binding?.blocker) {
statement = b.stmt(
b.call(b.member(node.metadata.binding.blocker, b.id('then')), b.thunk(b.block([statement])))
);
}
// Bindings need to happen after attribute updates, therefore after the render effect, and in order with events/actions.
// bind:this is a special case as it's one-way and could influence the render effect.
if (node.name === 'this') {
context.state.init.push(b.stmt(call));
context.state.init.push(statement);
} else {
const has_use =
parent.type === 'RegularElement' && parent.attributes.find((a) => a.type === 'UseDirective');
if (has_use) {
context.state.init.push(b.stmt(b.call('$.effect', b.thunk(call))));
if (defer) {
context.state.init.push(statement);
} else {
context.state.after_update.push(b.stmt(call));
context.state.after_update.push(statement);
}
}
}

@ -207,6 +207,7 @@ export namespace AST {
expression: Identifier | MemberExpression | SequenceExpression;
/** @internal */
metadata: {
binding?: Binding | null;
binding_group_name: Identifier;
parent_each_blocks: EachBlock[];
};

Loading…
Cancel
Save