mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
+22
-7
@@ -15,7 +15,7 @@ import { onWillUnmount } from "./hooks";
|
|||||||
export class Context extends EventBus {
|
export class Context extends EventBus {
|
||||||
state: any;
|
state: any;
|
||||||
observer: Observer;
|
observer: Observer;
|
||||||
id: number = 1;
|
rev: number = 1;
|
||||||
// mapping from component id to last observed context id
|
// mapping from component id to last observed context id
|
||||||
mapping: { [componentId: number]: number } = {};
|
mapping: { [componentId: number]: number } = {};
|
||||||
|
|
||||||
@@ -46,13 +46,13 @@ export class Context extends EventBus {
|
|||||||
* with the same depth in parallel.
|
* with the same depth in parallel.
|
||||||
*/
|
*/
|
||||||
async __notifyComponents() {
|
async __notifyComponents() {
|
||||||
const id = ++this.id;
|
const rev = ++this.rev;
|
||||||
const subs = this.subscriptions.update || [];
|
const subs = this.subscriptions.update || [];
|
||||||
for (let i = 0, iLen = subs.length; i < iLen; i++) {
|
for (let i = 0, iLen = subs.length; i < iLen; i++) {
|
||||||
const sub = subs[i];
|
const sub = subs[i];
|
||||||
const shouldCallback = sub.owner ? sub.owner.__owl__.isMounted : true;
|
const shouldCallback = sub.owner ? sub.owner.__owl__.isMounted : true;
|
||||||
if (shouldCallback) {
|
if (shouldCallback) {
|
||||||
const render = sub.callback.call(sub.owner, id);
|
const render = sub.callback.call(sub.owner, rev);
|
||||||
scheduler.flush();
|
scheduler.flush();
|
||||||
await render;
|
await render;
|
||||||
}
|
}
|
||||||
@@ -76,15 +76,30 @@ export function useContextWithCB(ctx: Context, component: Component<any, any>, m
|
|||||||
if (id in mapping) {
|
if (id in mapping) {
|
||||||
return ctx.state;
|
return ctx.state;
|
||||||
}
|
}
|
||||||
|
if (!__owl__.observer) {
|
||||||
|
__owl__.observer = new Observer();
|
||||||
|
__owl__.observer.notifyCB = component.render.bind(component);
|
||||||
|
}
|
||||||
|
const currentCB = __owl__.observer.notifyCB;
|
||||||
|
__owl__.observer.notifyCB = function () {
|
||||||
|
if (ctx.rev > mapping[id]) {
|
||||||
|
// in this case, the context has been updated since we were rendering
|
||||||
|
// last, and we do not need to render here with the observer. A
|
||||||
|
// rendering is coming anyway, with the correct props.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
currentCB();
|
||||||
|
}
|
||||||
|
|
||||||
mapping[id] = 0;
|
mapping[id] = 0;
|
||||||
const renderFn = __owl__.renderFn;
|
const renderFn = __owl__.renderFn;
|
||||||
__owl__.renderFn = function(comp, params) {
|
__owl__.renderFn = function(comp, params) {
|
||||||
mapping[id] = ctx.id;
|
mapping[id] = ctx.rev;
|
||||||
return renderFn(comp, params);
|
return renderFn(comp, params);
|
||||||
};
|
};
|
||||||
ctx.on("update", component, async contextId => {
|
ctx.on("update", component, async contextRev => {
|
||||||
if (mapping[id] < contextId) {
|
if (mapping[id] < contextRev) {
|
||||||
mapping[id] = contextId;
|
mapping[id] = contextRev;
|
||||||
await method();
|
await method();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -174,7 +174,7 @@ describe("Context", () => {
|
|||||||
expect(testContext.subscriptions.update.length).toBe(0);
|
expect(testContext.subscriptions.update.length).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
test.skip("concurrent renderings", async () => {
|
test("concurrent renderings", async () => {
|
||||||
const testContext = new Context({ x: { n: 1 }, key: "x" });
|
const testContext = new Context({ x: { n: 1 }, key: "x" });
|
||||||
const def = makeDeferred();
|
const def = makeDeferred();
|
||||||
let stateC;
|
let stateC;
|
||||||
@@ -207,7 +207,7 @@ describe("Context", () => {
|
|||||||
|
|
||||||
expect(fixture.innerHTML).toBe("<div><p><span>1a</span></p></div>");
|
expect(fixture.innerHTML).toBe("<div><p><span>1a</span></p></div>");
|
||||||
testContext.state.key = "y";
|
testContext.state.key = "y";
|
||||||
testContext.state.y = 2;
|
testContext.state.y = {n: 2};
|
||||||
delete testContext.state.x;
|
delete testContext.state.x;
|
||||||
await nextTick();
|
await nextTick();
|
||||||
|
|
||||||
@@ -219,6 +219,6 @@ describe("Context", () => {
|
|||||||
def.resolve();
|
def.resolve();
|
||||||
await nextTick();
|
await nextTick();
|
||||||
|
|
||||||
expect(fixture.innerHTML).toBe("<div><p><span>1a</span></p></div>");
|
expect(fixture.innerHTML).toBe("<div><p><span>2b</span></p></div>");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user