mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
small refactoring to prepare async work
This commit is contained in:
@@ -112,12 +112,12 @@ export class Component<
|
|||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
async mount(target: HTMLElement): Promise<void> {
|
async mount(target: HTMLElement): Promise<void> {
|
||||||
await this._start();
|
const vnode = await this._start();
|
||||||
await this.render();
|
if (this.__widget__.isDestroyed) {
|
||||||
if (!this.el) {
|
|
||||||
// widget was destroyed before we get here...
|
// widget was destroyed before we get here...
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
this._patch(vnode);
|
||||||
target.appendChild(this.el!);
|
target.appendChild(this.el!);
|
||||||
|
|
||||||
if (document.body.contains(target)) {
|
if (document.body.contains(target)) {
|
||||||
@@ -204,13 +204,16 @@ export class Component<
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const vnode = await this._render();
|
const vnode = await this._render();
|
||||||
|
this._patch(vnode);
|
||||||
|
}
|
||||||
|
|
||||||
|
private _patch(vnode) {
|
||||||
this.__widget__.vnode = patch(
|
this.__widget__.vnode = patch(
|
||||||
this.__widget__.vnode || document.createElement(vnode.sel!),
|
this.__widget__.vnode || document.createElement(vnode.sel!),
|
||||||
vnode
|
vnode
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
private async _start(): Promise<VNode> {
|
||||||
private async _start(): Promise<void> {
|
|
||||||
await this.willStart();
|
await this.willStart();
|
||||||
if (!this.__widget__.isDestroyed) {
|
if (!this.__widget__.isDestroyed) {
|
||||||
this.__widget__.isStarted = true;
|
this.__widget__.isStarted = true;
|
||||||
@@ -218,9 +221,10 @@ export class Component<
|
|||||||
if (this.inlineTemplate) {
|
if (this.inlineTemplate) {
|
||||||
this.env.qweb.addTemplate(this.inlineTemplate, this.inlineTemplate, true);
|
this.env.qweb.addTemplate(this.inlineTemplate, this.inlineTemplate, true);
|
||||||
}
|
}
|
||||||
|
return this._render();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _render(): Promise<VNode> {
|
async _render(): Promise<VNode> {
|
||||||
const promises: Promise<void>[] = [];
|
const promises: Promise<void>[] = [];
|
||||||
const template = this.inlineTemplate || this.template;
|
const template = this.inlineTemplate || this.template;
|
||||||
let vnode = this.env.qweb.render(template, this, { promises });
|
let vnode = this.env.qweb.render(template, this, { promises });
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
import { Component, WEnv } from "../../src/ts/core/component";
|
import { Component, WEnv } from "../../src/ts/core/component";
|
||||||
import {
|
import {
|
||||||
|
makeDeferred,
|
||||||
makeTestFixture,
|
makeTestFixture,
|
||||||
makeTestWEnv,
|
makeTestWEnv,
|
||||||
nextMicroTick,
|
nextMicroTick,
|
||||||
|
nextTick,
|
||||||
normalize
|
normalize
|
||||||
} from "../helpers";
|
} from "../helpers";
|
||||||
|
|
||||||
@@ -107,9 +109,9 @@ describe("basic widget properties", () => {
|
|||||||
async willStart() {
|
async willStart() {
|
||||||
this.updateState({});
|
this.updateState({});
|
||||||
}
|
}
|
||||||
async render() {
|
async _render() {
|
||||||
renderCalls++;
|
renderCalls++;
|
||||||
return super.render();
|
return super._render();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const widget = new TestW(env);
|
const widget = new TestW(env);
|
||||||
@@ -448,14 +450,11 @@ describe("destroy method", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("destroying a widget before willStart is done", async () => {
|
test("destroying a widget before willStart is done", async () => {
|
||||||
let resolve;
|
let def = makeDeferred();
|
||||||
let isRendered = false;
|
let isRendered = false;
|
||||||
let p: Promise<void> = new Promise(function(r) {
|
|
||||||
resolve = r;
|
|
||||||
});
|
|
||||||
class DelayedWidget extends Widget {
|
class DelayedWidget extends Widget {
|
||||||
willStart() {
|
willStart() {
|
||||||
return p;
|
return def;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect(fixture.innerHTML).toBe("");
|
expect(fixture.innerHTML).toBe("");
|
||||||
@@ -468,12 +467,8 @@ describe("destroy method", () => {
|
|||||||
expect(widget.__widget__.isMounted).toBe(false);
|
expect(widget.__widget__.isMounted).toBe(false);
|
||||||
expect(widget.__widget__.isStarted).toBe(false);
|
expect(widget.__widget__.isStarted).toBe(false);
|
||||||
expect(widget.__widget__.isDestroyed).toBe(true);
|
expect(widget.__widget__.isDestroyed).toBe(true);
|
||||||
resolve();
|
def.resolve();
|
||||||
// Note: should we abandon await and not have to do this?
|
await nextTick();
|
||||||
// TODO: talk to vsc
|
|
||||||
await nextMicroTick();
|
|
||||||
await nextMicroTick();
|
|
||||||
await nextMicroTick();
|
|
||||||
|
|
||||||
expect(widget.__widget__.isStarted).toBe(false);
|
expect(widget.__widget__.isStarted).toBe(false);
|
||||||
expect(widget.__widget__.isMounted).toBe(false);
|
expect(widget.__widget__.isMounted).toBe(false);
|
||||||
|
|||||||
@@ -199,3 +199,19 @@ export function nextMicroTick(): Promise<void> {
|
|||||||
export function nextTick(): Promise<void> {
|
export function nextTick(): Promise<void> {
|
||||||
return new Promise(resolve => setTimeout(resolve));
|
return new Promise(resolve => setTimeout(resolve));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface Deferred extends Promise<any> {
|
||||||
|
resolve(val?: any): void;
|
||||||
|
reject(): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function makeDeferred(): Deferred {
|
||||||
|
let resolve, reject;
|
||||||
|
let def = new Promise((_resolve, _reject) => {
|
||||||
|
resolve = _resolve;
|
||||||
|
reject = _reject;
|
||||||
|
});
|
||||||
|
(<Deferred>def).resolve = resolve;
|
||||||
|
(<Deferred>def).reject = reject;
|
||||||
|
return <Deferred>def;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user