[FIX] store: properly observe all array methods

This commit is contained in:
Géry Debongnie
2019-04-12 13:03:25 +02:00
parent 8ca806eb28
commit 4f1d976206
2 changed files with 72 additions and 10 deletions
+33 -10
View File
@@ -158,17 +158,40 @@ export function makeObserver(): Observer {
const ArrayProto = Array.prototype;
const ModifiedArrayProto = Object.create(ArrayProto);
ModifiedArrayProto.push = function(...args) {
observer.__rev__++;
this.__rev__++;
return ArrayProto.push.call(this, ...args);
};
const methodsToPatch = [
"push",
"pop",
"shift",
"unshift",
"splice",
"sort",
"reverse"
];
for (let method of methodsToPatch) {
const initialMethod = ArrayProto[method];
ModifiedArrayProto[method] = function(...args) {
observer.__rev__++;
this.__rev__++;
let inserted;
switch (method) {
case "push":
case "unshift":
inserted = args;
break;
case "splice":
inserted = args.slice(2);
break;
}
if (inserted) {
for (let elem of inserted) {
observe(elem);
}
}
return initialMethod.call(this, ...args);
};
}
ModifiedArrayProto.pop = function(...args) {
observer.__rev__++;
this.__rev__++;
return ArrayProto.pop.call(this, ...args);
};
function observeArr(arr: Array<any>) {
(<any>arr).__rev__ = 0;
Object.defineProperty(arr, "__rev__", { enumerable: false });
+39
View File
@@ -210,6 +210,45 @@ describe("observer", () => {
expect(arr.__rev__).toBe(1);
expect(observer.__rev__).toBe(1);
expect(arr.length).toBe(1);
arr.splice(1, 0, "hey");
expect(arr.__rev__).toBe(2);
expect(observer.__rev__).toBe(2);
expect(arr.length).toBe(2);
arr.unshift("lindemans");
expect(arr.__rev__).toBe(3);
arr.reverse();
expect(arr.__rev__).toBe(4);
arr.pop();
expect(arr.__rev__).toBe(5);
arr.shift();
expect(arr.__rev__).toBe(6);
arr.sort();
expect(arr.__rev__).toBe(7);
expect(arr).toEqual([1]);
});
test("object pushed into arrays are observed", () => {
const observer = makeObserver();
const arr: any = [];
observer.observe(arr);
expect(observer.__rev__).toBe(0);
arr.push({ kriek: 5 });
expect(observer.__rev__).toBe(1);
expect(arr.__rev__).toBe(1);
expect(arr[0].__rev__).toBe(0);
arr[0].kriek = 6;
expect(observer.__rev__).toBe(2);
expect(arr.__rev__).toBe(1);
expect(arr[0].__rev__).toBe(1);
});
test("properly observe arrays in object", () => {