mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[FIX] reactivity: don't subscribe to keys when making reactive
When attempting to create a reactive object, we first check if the target can be made reactive, this is done with Object.toString, which internally reads the Symbol.toStringTag on the underlying object. When trying to make a reactive object from another, for example when reobserving a reactive or when reading a reactive object from the context of another, this would read the subscribe the original object to the Symbol.toStringTag property. This commit fixes that by calling Object.toString on the underlying target object where applicable.
This commit is contained in:
committed by
Géry Debongnie
parent
203ac7ac66
commit
39329f80b2
@@ -28,7 +28,7 @@ const COLLECTION_RAWTYPES = new Set(["Set", "Map", "WeakMap"]);
|
|||||||
* @returns the raw type of the object
|
* @returns the raw type of the object
|
||||||
*/
|
*/
|
||||||
function rawType(obj: any) {
|
function rawType(obj: any) {
|
||||||
return objectToString.call(obj).slice(8, -1);
|
return objectToString.call(toRaw(obj)).slice(8, -1);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Checks whether a given value can be made into a reactive object.
|
* Checks whether a given value can be made into a reactive object.
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import {
|
|||||||
markRaw,
|
markRaw,
|
||||||
toRaw,
|
toRaw,
|
||||||
} from "../src";
|
} from "../src";
|
||||||
import { reactive } from "../src/runtime/reactivity";
|
import { reactive, getSubscriptions } from "../src/runtime/reactivity";
|
||||||
import { batched } from "../src/runtime/utils";
|
import { batched } from "../src/runtime/utils";
|
||||||
import {
|
import {
|
||||||
makeDeferred,
|
makeDeferred,
|
||||||
@@ -1020,6 +1020,32 @@ describe("Reactivity", () => {
|
|||||||
expect(n3).toBe(2);
|
expect(n3).toBe(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("reactive inside other: reading the inner reactive from outer doesn't affect the inner's subscriptions", async () => {
|
||||||
|
const getObservedKeys = (obj: any) => getSubscriptions(obj).flatMap(({ keys }) => keys);
|
||||||
|
let n1 = 0;
|
||||||
|
let n2 = 0;
|
||||||
|
const innerCb = () => n1++;
|
||||||
|
const outerCb = () => n2++;
|
||||||
|
const inner = createReactive({ a: 1 }, innerCb);
|
||||||
|
const outer = createReactive({ b: inner }, outerCb);
|
||||||
|
expect(n1).toBe(0);
|
||||||
|
expect(n2).toBe(0);
|
||||||
|
expect(getObservedKeys(innerCb)).toEqual([]);
|
||||||
|
expect(getObservedKeys(outerCb)).toEqual([]);
|
||||||
|
|
||||||
|
outer.b.a;
|
||||||
|
expect(getObservedKeys(innerCb)).toEqual([]);
|
||||||
|
expect(getObservedKeys(outerCb)).toEqual(["b", "a"]);
|
||||||
|
expect(n1).toBe(0);
|
||||||
|
expect(n2).toBe(0);
|
||||||
|
|
||||||
|
outer.b.a = 2;
|
||||||
|
expect(getObservedKeys(innerCb)).toEqual([]);
|
||||||
|
expect(getObservedKeys(outerCb)).toEqual([]);
|
||||||
|
expect(n1).toBe(0);
|
||||||
|
expect(n2).toBe(1);
|
||||||
|
});
|
||||||
|
|
||||||
// test("notification is not done after unregistration", async () => {
|
// test("notification is not done after unregistration", async () => {
|
||||||
// let n = 0;
|
// let n = 0;
|
||||||
// const observer = () => n++;
|
// const observer = () => n++;
|
||||||
|
|||||||
Reference in New Issue
Block a user