mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| aef6923c23 |
@@ -120,20 +120,30 @@ export class ComponentNode<P = any, E = any> implements VNode<ComponentNode<P, E
|
|||||||
this.initiateRender(fiber);
|
this.initiateRender(fiber);
|
||||||
}
|
}
|
||||||
|
|
||||||
async initiateRender(fiber: Fiber | MountFiber) {
|
initiateRender(fiber: Fiber | MountFiber) {
|
||||||
this.fiber = fiber;
|
this.fiber = fiber;
|
||||||
if (this.mounted.length) {
|
if (this.mounted.length) {
|
||||||
fiber.root!.mounted.push(fiber);
|
fiber.root!.mounted.push(fiber);
|
||||||
}
|
}
|
||||||
const component = this.component;
|
const component = this.component;
|
||||||
|
const finish = () => {
|
||||||
|
if (this.status === STATUS.NEW && this.fiber === fiber) {
|
||||||
|
this._render(fiber);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let willStartResults;
|
||||||
try {
|
try {
|
||||||
await Promise.all(this.willStart.map((f) => f.call(component)));
|
willStartResults = this.willStart.map((f) => f.call(component));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
handleError({ node: this, error: e });
|
handleError({ node: this, error: e });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (this.status === STATUS.NEW && this.fiber === fiber) {
|
if (willStartResults.some(result => result instanceof Promise)) {
|
||||||
this._render(fiber);
|
Promise.all(willStartResults)
|
||||||
|
.then(finish)
|
||||||
|
.catch(e => handleError({ node: this, error: e }));
|
||||||
|
} else {
|
||||||
|
finish();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,8 +163,8 @@ export class ComponentNode<P = any, E = any> implements VNode<ComponentNode<P, E
|
|||||||
|
|
||||||
const fiber = makeRootFiber(this);
|
const fiber = makeRootFiber(this);
|
||||||
this.fiber = fiber;
|
this.fiber = fiber;
|
||||||
this.app.scheduler.addFiber(fiber);
|
debugger;
|
||||||
await Promise.resolve();
|
window.requestAnimationFrame(() => {
|
||||||
if (this.status === STATUS.DESTROYED) {
|
if (this.status === STATUS.DESTROYED) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -172,6 +182,8 @@ export class ComponentNode<P = any, E = any> implements VNode<ComponentNode<P, E
|
|||||||
if (this.fiber === fiber && (current || !fiber.parent)) {
|
if (this.fiber === fiber && (current || !fiber.parent)) {
|
||||||
this._render(fiber);
|
this._render(fiber);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
this.app.scheduler.addFiber(fiber);
|
||||||
}
|
}
|
||||||
|
|
||||||
_render(fiber: Fiber | RootFiber) {
|
_render(fiber: Fiber | RootFiber) {
|
||||||
@@ -207,14 +219,14 @@ export class ComponentNode<P = any, E = any> implements VNode<ComponentNode<P, E
|
|||||||
this.status = STATUS.DESTROYED;
|
this.status = STATUS.DESTROYED;
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateAndRender(props: any, parentFiber: Fiber) {
|
updateAndRender(props: any, parentFiber: Fiber) {
|
||||||
// update
|
// update
|
||||||
const fiber = makeChildFiber(this, parentFiber);
|
const fiber = makeChildFiber(this, parentFiber);
|
||||||
this.fiber = fiber;
|
this.fiber = fiber;
|
||||||
const component = this.component;
|
const component = this.component;
|
||||||
applyDefaultProps(props, component.constructor as any);
|
applyDefaultProps(props, component.constructor as any);
|
||||||
const prom = Promise.all(this.willUpdateProps.map((f) => f.call(component, props)));
|
|
||||||
await prom;
|
const finish = () => {
|
||||||
if (fiber !== this.fiber) {
|
if (fiber !== this.fiber) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -228,6 +240,13 @@ export class ComponentNode<P = any, E = any> implements VNode<ComponentNode<P, E
|
|||||||
parentRoot.patched.push(fiber);
|
parentRoot.patched.push(fiber);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const willUpdatePropsResults = this.willUpdateProps.map((f) => f.call(component, props));
|
||||||
|
if (willUpdatePropsResults.some(res => res instanceof Promise)) {
|
||||||
|
Promise.all(willUpdatePropsResults).then(finish);
|
||||||
|
} else {
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds a child that has dom that is not yet updated, and update it. This
|
* Finds a child that has dom that is not yet updated, and update it. This
|
||||||
|
|||||||
@@ -97,17 +97,14 @@ test("destroying/recreating a subwidget with different props (if start is not ov
|
|||||||
expect(["W:setup", "W:willStart", "W:willRender", "W:rendered", "W:mounted"]).toBeLogged();
|
expect(["W:setup", "W:willStart", "W:willRender", "W:rendered", "W:mounted"]).toBeLogged();
|
||||||
|
|
||||||
expect(n).toBe(0);
|
expect(n).toBe(0);
|
||||||
|
|
||||||
w.state.val = 2;
|
w.state.val = 2;
|
||||||
await nextMicroTick();
|
await new Promise(requestAnimationFrame); // calls to _render are batched per animation frame
|
||||||
await nextMicroTick();
|
|
||||||
expect(n).toBe(1);
|
expect(n).toBe(1);
|
||||||
|
|
||||||
expect(["W:willRender", "Child:setup", "Child:willStart", "W:rendered"]).toBeLogged();
|
expect(["W:willRender", "Child:setup", "Child:willStart", "W:rendered"]).toBeLogged();
|
||||||
|
|
||||||
w.state.val = 3;
|
w.state.val = 3;
|
||||||
await nextMicroTick();
|
await new Promise(requestAnimationFrame);
|
||||||
await nextMicroTick();
|
|
||||||
expect(n).toBe(2);
|
expect(n).toBe(2);
|
||||||
|
|
||||||
expect([
|
expect([
|
||||||
|
|||||||
Reference in New Issue
Block a user