Fix bind:this not working in onMount

If a component was instantiated with new Component(), its onMount
callback was being called before the bind:this bindings were set up, so
that the binding variable was undefined. Now the bind:this bindings are
properly bound before the onMount callbacks are called.
pull/6920/head
Robin Munn 5 years ago
parent 78e02565d2
commit 50cc07ec93

@ -1,7 +1,7 @@
import { run_all } from './utils';
import { run_all, Queue } from './utils';
import { set_current_component } from './lifecycle';
export const dirty_components = [];
export const dirty_components = new Queue<any>();
export const intros = { enabled: false };
export const binding_callbacks = [];
@ -31,17 +31,14 @@ export function add_flush_callback(fn) {
flush_callbacks.push(fn);
}
let flushing = false;
const seen_callbacks = new Set();
export function flush() {
if (flushing) return;
flushing = true;
do {
// first, call beforeUpdate functions
// and update components
for (let i = 0; i < dirty_components.length; i += 1) {
const component = dirty_components[i];
while (dirty_components.length) {
const component = dirty_components.shift();
set_current_component(component);
update(component.$$);
}
@ -73,7 +70,6 @@ export function flush() {
}
update_scheduled = false;
flushing = false;
seen_callbacks.clear();
}

@ -58,6 +58,40 @@ export function is_empty(obj) {
return Object.keys(obj).length === 0;
}
export class Queue<T> {
forward: T[];
reverse: T[];
constructor() {
this.forward = [];
this.reverse = [];
}
push(value: T) {
return this.forward.push(value);
}
shift() {
if (this.reverse.length === 0) {
while (this.forward.length) {
this.reverse.push(this.forward.pop());
}
}
return this.reverse.pop();
}
get length() {
return this.forward.length + this.reverse.length;
}
set length(len: number) {
if (len === 0) {
this.forward.length = 0;
this.reverse.length = 0;
} else {
while (this.length > len) {
this.shift();
}
}
}
}
export function validate_store(store, name) {
if (store != null && typeof store.subscribe !== 'function') {
throw new Error(`'${name}' is not a store with a 'subscribe' method`);

@ -0,0 +1,15 @@
<script>
import { onMount } from 'svelte';
let element;
let bound = false;
onMount(() => {
if (element) bound = true;
});
</script>
<div bind:this={element}></div>
<p>
Bound? {bound}
</p>

@ -0,0 +1,11 @@
export default {
async test({ assert, target }) {
assert.htmlEqual(target.innerHTML, `
<div id="target"><div></div>
<p>
Bound? true
</p>
</div>
`);
}
};

@ -0,0 +1,13 @@
<script>
import Mount from './Mount.svelte';
import { onMount } from 'svelte';
onMount(() => {
const component = new Mount({
target: document.querySelector('#target'),
props: {},
});
});
</script>
<div id="target" />
Loading…
Cancel
Save