mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[FIX] store: properly call onUpdate functions in some cases
Before this commit, the following scenario could happen: Suppose that we have a parent component A, connected to a store, and a child component B, also connected to the store and using the onUpdate feature. Then, we remount the A component in some other places and a rendering is initiated in A. We immediately update the store state. What happens next is: - rendering A is done, A internal revid is updated - store update A (but nothing is done because the state change here does not modify A) - rendering B is done (from parent), B internal revid is updated - store update B, notice internal revid is updated, does not call the onUpdate function We then have the B component which has not its internal state updated, because we did not call its onUpdate function. The solution is to move the onUpdate call in a "preupdate" event, to be sure that it is called everytime the store is updated. closes #816
This commit is contained in:
+14
-3
@@ -75,6 +75,11 @@ export class Store extends Context {
|
||||
);
|
||||
return result;
|
||||
}
|
||||
|
||||
__notifyComponents(): Promise<void> {
|
||||
this.trigger("before-update");
|
||||
return super.__notifyComponents();
|
||||
}
|
||||
}
|
||||
|
||||
interface SelectorOptions {
|
||||
@@ -105,13 +110,16 @@ export function useStore(selector, options: SelectorOptions = {}): any {
|
||||
const newRevNumber = hashFn(result);
|
||||
if ((newRevNumber > 0 && revNumber !== newRevNumber) || !isEqual(oldResult, result)) {
|
||||
revNumber = newRevNumber;
|
||||
if (options.onUpdate) {
|
||||
options.onUpdate(result);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (options.onUpdate) {
|
||||
store.on("before-update", component, () => {
|
||||
const newValue = selector(store!.state, component.props!);
|
||||
options.onUpdate(newValue);
|
||||
});
|
||||
}
|
||||
store.updateFunctions[componentId].push(function (): boolean {
|
||||
return selectCompareUpdate(store!.state, component.props);
|
||||
});
|
||||
@@ -132,6 +140,9 @@ export function useStore(selector, options: SelectorOptions = {}): any {
|
||||
const __destroy = component.__destroy;
|
||||
component.__destroy = (parent) => {
|
||||
delete store.updateFunctions[componentId];
|
||||
if (options.onUpdate) {
|
||||
store.off("before-update", component);
|
||||
}
|
||||
__destroy.call(component, parent);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user