mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[REF] observer: move batch code out of store, add notifycb
This commit is contained in:
+16
-3
@@ -18,7 +18,7 @@ const ModifiedArrayProto = Object.create(ArrayProto);
|
|||||||
for (let method of methodsToPatch) {
|
for (let method of methodsToPatch) {
|
||||||
const initialMethod = ArrayProto[method];
|
const initialMethod = ArrayProto[method];
|
||||||
ModifiedArrayProto[method] = function(...args) {
|
ModifiedArrayProto[method] = function(...args) {
|
||||||
this.__observer__.rev++;
|
this.__observer__.notifyChange();
|
||||||
this.__owl__.rev++;
|
this.__owl__.rev++;
|
||||||
let parent = this;
|
let parent = this;
|
||||||
do {
|
do {
|
||||||
@@ -46,6 +46,19 @@ for (let method of methodsToPatch) {
|
|||||||
export class Observer {
|
export class Observer {
|
||||||
rev: number = 1;
|
rev: number = 1;
|
||||||
allowMutations: boolean = true;
|
allowMutations: boolean = true;
|
||||||
|
dirty: boolean = false;
|
||||||
|
|
||||||
|
notifyCB() {}
|
||||||
|
notifyChange() {
|
||||||
|
this.rev++;
|
||||||
|
this.dirty = true;
|
||||||
|
Promise.resolve().then(() => {
|
||||||
|
if (this.dirty) {
|
||||||
|
this.dirty = false;
|
||||||
|
this.notifyCB();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
observe(value: any, parent?: any) {
|
observe(value: any, parent?: any) {
|
||||||
if (value === null) {
|
if (value === null) {
|
||||||
@@ -69,7 +82,7 @@ export class Observer {
|
|||||||
set(target: any, key: number | string, value: any) {
|
set(target: any, key: number | string, value: any) {
|
||||||
this._addProp(target, key, value);
|
this._addProp(target, key, value);
|
||||||
target.__owl__.rev++;
|
target.__owl__.rev++;
|
||||||
this.rev++;
|
this.notifyChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
unobserve(target: any) {
|
unobserve(target: any) {
|
||||||
@@ -119,11 +132,11 @@ export class Observer {
|
|||||||
value = newVal;
|
value = newVal;
|
||||||
self.observe(newVal, obj);
|
self.observe(newVal, obj);
|
||||||
obj.__owl__.rev!++;
|
obj.__owl__.rev!++;
|
||||||
self.rev++;
|
|
||||||
let parent = obj;
|
let parent = obj;
|
||||||
do {
|
do {
|
||||||
parent.__owl__.deepRev++;
|
parent.__owl__.deepRev++;
|
||||||
} while ((parent = parent.__owl__.parent));
|
} while ((parent = parent.__owl__.parent));
|
||||||
|
self.notifyChange();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
+1
-11
@@ -22,7 +22,6 @@ export class Store extends EventBus {
|
|||||||
actions: any;
|
actions: any;
|
||||||
mutations: any;
|
mutations: any;
|
||||||
_commitLevel: number = 0;
|
_commitLevel: number = 0;
|
||||||
_isMutating: boolean = false;
|
|
||||||
history: any[] = [];
|
history: any[] = [];
|
||||||
debug: boolean;
|
debug: boolean;
|
||||||
env: any;
|
env: any;
|
||||||
@@ -37,6 +36,7 @@ export class Store extends EventBus {
|
|||||||
this.mutations = config.mutations;
|
this.mutations = config.mutations;
|
||||||
this.env = config.env;
|
this.env = config.env;
|
||||||
this.observer = new Observer();
|
this.observer = new Observer();
|
||||||
|
this.observer.notifyCB = this.trigger.bind(this, "update");
|
||||||
this.observer.allowMutations = false;
|
this.observer.allowMutations = false;
|
||||||
this.observer.observe(this.state);
|
this.observer.observe(this.state);
|
||||||
|
|
||||||
@@ -72,8 +72,6 @@ export class Store extends EventBus {
|
|||||||
throw new Error(`[Error] mutation ${type} is undefined`);
|
throw new Error(`[Error] mutation ${type} is undefined`);
|
||||||
}
|
}
|
||||||
this._commitLevel++;
|
this._commitLevel++;
|
||||||
const currentRev = this.observer.rev;
|
|
||||||
this._isMutating = true;
|
|
||||||
this.observer.allowMutations = true;
|
this.observer.allowMutations = true;
|
||||||
|
|
||||||
const res = this.mutations[type].call(
|
const res = this.mutations[type].call(
|
||||||
@@ -95,14 +93,6 @@ export class Store extends EventBus {
|
|||||||
payload: payload
|
payload: payload
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Promise.resolve().then(() => {
|
|
||||||
if (this._isMutating) {
|
|
||||||
this._isMutating = false;
|
|
||||||
if (currentRev !== this.observer.rev) {
|
|
||||||
this.trigger("update", this.state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
this._commitLevel--;
|
this._commitLevel--;
|
||||||
return res;
|
return res;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { Observer } from "../src/observer";
|
import { Observer } from "../src/observer";
|
||||||
|
import { nextMicroTick } from "./helpers";
|
||||||
|
|
||||||
describe("observer", () => {
|
describe("observer", () => {
|
||||||
test("properly observe objects", () => {
|
test("properly observe objects", () => {
|
||||||
@@ -252,4 +253,30 @@ describe("observer", () => {
|
|||||||
expect(obj1.__owl__.rev).toBe(1);
|
expect(obj1.__owl__.rev).toBe(1);
|
||||||
expect(obj2.__owl__.rev).toBe(2);
|
expect(obj2.__owl__.rev).toBe(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("call callback when state is changed", async () => {
|
||||||
|
const observer = new Observer();
|
||||||
|
observer.notifyCB = jest.fn();
|
||||||
|
const obj: any = { a: 1, b: { c: 2 }, d: [{ e: 3 }], f: 4 };
|
||||||
|
|
||||||
|
observer.observe(obj);
|
||||||
|
expect(observer.notifyCB).toBeCalledTimes(0);
|
||||||
|
|
||||||
|
obj.a = 2;
|
||||||
|
await nextMicroTick();
|
||||||
|
expect(observer.notifyCB).toBeCalledTimes(1);
|
||||||
|
|
||||||
|
obj.b.c = 3;
|
||||||
|
await nextMicroTick();
|
||||||
|
expect(observer.notifyCB).toBeCalledTimes(2);
|
||||||
|
|
||||||
|
obj.d[0].e = 5;
|
||||||
|
await nextMicroTick();
|
||||||
|
expect(observer.notifyCB).toBeCalledTimes(3);
|
||||||
|
|
||||||
|
obj.a = 111;
|
||||||
|
obj.f = 222;
|
||||||
|
await nextMicroTick();
|
||||||
|
expect(observer.notifyCB).toBeCalledTimes(4);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user