summaryrefslogtreecommitdiff
path: root/addons/web/static/src
diff options
context:
space:
mode:
authorJulien Mougenot <jum@odoo.com>2020-07-31 11:46:14 +0000
committerJulien Mougenot <jum@odoo.com>2020-08-04 12:44:18 +0000
commitf8ab35f9e18d033cb9fa2b28c6abe3689afc774a (patch)
treef6d91f29fe936bf4291d945b9e6147f3a40947c6 /addons/web/static/src
parent918ccf5b0eb6b8e6f8d789f204bc3ce4134b797f (diff)
[IMP] web: Model: small simplifications
Small refactor of some aspects of the main model.js class to make it more consistent and extensible.
Diffstat (limited to 'addons/web/static/src')
-rw-r--r--addons/web/static/src/js/model.js111
1 files changed, 59 insertions, 52 deletions
diff --git a/addons/web/static/src/js/model.js b/addons/web/static/src/js/model.js
index b86599eb5fc..51959450216 100644
--- a/addons/web/static/src/js/model.js
+++ b/addons/web/static/src/js/model.js
@@ -20,7 +20,7 @@ odoo.define("web/static/src/js/model.js", function (require) {
constructor(config) {
this.config = config;
this.env = this.config.env;
- this._shouldLoad = true;
+ this.shouldLoad = true;
this.state = {};
}
@@ -30,12 +30,23 @@ odoo.define("web/static/src/js/model.js", function (require) {
/**
* Used by the parent model to initiate a load action. The actual
- * loading of the extension is determined by the "_shouldLoad" property.
+ * loading of the extension is determined by the "shouldLoad" property.
+ * @param {Object} params
*/
- async callLoad() {
- if (this._shouldLoad) {
- this._shouldLoad = false;
- await this.load();
+ async callLoad(params) {
+ if (this.shouldLoad) {
+ this.shouldLoad = false;
+ await this.load(params);
+ }
+ }
+
+ /**
+ * @param {string} method
+ * @param {...any} args
+ */
+ dispatch(method, ...args) {
+ if (method in this) {
+ this[method](...args);
}
}
@@ -65,8 +76,8 @@ odoo.define("web/static/src/js/model.js", function (require) {
* @param {Object} [state]
*/
importState(state) {
- this._shouldLoad = !state;
- if (this._shouldLoad) {
+ this.shouldLoad = !state;
+ if (this.shouldLoad) {
this.prepareState();
} else {
Object.assign(this.state, state);
@@ -76,9 +87,10 @@ odoo.define("web/static/src/js/model.js", function (require) {
/**
* Called and awaited on initial model load.
* @abstract
+ * @param {Object} params
* @returns {Promise}
*/
- async load() {
+ async load(/* params */) {
/* ... */
}
@@ -90,15 +102,6 @@ odoo.define("web/static/src/js/model.js", function (require) {
prepareState() {
/* ... */
}
-
- /**
- * Called and awaited after an action dispatch.
- * @abstract
- * @returns {Promise}
- */
- async reloadAfterDispatch() {
- /* ... */
- }
}
/**
* The layer of an extension indicates with which other extensions this one
@@ -285,40 +288,32 @@ odoo.define("web/static/src/js/model.js", function (require) {
* extension. This method must be overridden if multiple extensions
* return a value with a common method (and dispatchAll does not
* suffice). After the dispatch of the action, all models are partially
- * reloaded (@see ModelExtension.reloadAfterDispatch()) and components
- * are notified afterwards.
+ * reloaded and components are notified afterwards.
+ * @param {string} method
+ * @param {...any} args
*/
dispatch(method, ...args) {
const isInitialDispatch = !this.dispatching;
this.dispatching = true;
for (const extension of this.extensions.flat()) {
- if (method in extension) {
- extension[method](...args);
- }
+ extension.dispatch(method, ...args);
}
- if (isInitialDispatch) {
- this.dispatching = false;
- (async () => {
- // Calls 'after dispatch' hooks
- // Purpose: fetch updated data from the server. This is
- // considered a loading action and is thus performed by groups
- // instead of loading all extensions at once.
- for (let layer = 0; layer < this.extensions.length; layer++) {
- const afterDispatchPromises = [];
- for (const extension of this.extensions[layer]) {
- afterDispatchPromises.push(extension.reloadAfterDispatch());
- }
- await Promise.all(afterDispatchPromises);
- }
- // Notifies subscribed components
- // Purpose: re-render components bound by 'useModel'
- let rev = this.rev;
- await Promise.resolve();
- if (rev === this.rev) {
- this._notifyComponents();
- }
- })();
+ if (!isInitialDispatch) {
+ return;
}
+ this.dispatching = false;
+ let rev = this.rev;
+ // Calls 'after dispatch' hooks
+ // Purpose: fetch updated data from the server. This is considered
+ // a loading action and is thus performed by groups instead of
+ // loading all extensions at once.
+ this._loadExtensions({ isInitialLoad: false }).then(() => {
+ // Notifies subscribed components
+ // Purpose: re-render components bound by 'useModel'
+ if (rev === this.rev) {
+ this._notifyComponents();
+ }
+ });
}
/**
@@ -378,13 +373,7 @@ odoo.define("web/static/src/js/model.js", function (require) {
* @returns {Promise}
*/
async load() {
- for (let layer = 0; layer < this.extensions.length; layer++) {
- const layerPromises = [];
- for (const extension of this.extensions[layer]) {
- layerPromises.push(extension.callLoad());
- }
- await Promise.all(layerPromises);
- }
+ await this._loadExtensions({ isInitialLoad: true });
}
//---------------------------------------------------------------------
@@ -417,6 +406,24 @@ odoo.define("web/static/src/js/model.js", function (require) {
}
/**
+ * Private handler to loop over all extension layers sequencially and
+ * wait for a given callback to be completed on all extensions of a
+ * same layer.
+ * @private
+ * @param {Object} params
+ * @param {boolean} params.isInitialLoad whether this call comes
+ * from the initial load.
+ * @returns {Promise}
+ */
+ async _loadExtensions(params) {
+ for (let layer = 0; layer < this.extensions.length; layer++) {
+ await Promise.all(this.extensions[layer].map(
+ (extension) => extension.callLoad(params)
+ ));
+ }
+ }
+
+ /**
* @see Context.__notifyComponents() in owl.js for explanation
* @private
*/