diff options
| author | Julien Mougenot <jum@odoo.com> | 2020-07-31 11:46:14 +0000 |
|---|---|---|
| committer | Julien Mougenot <jum@odoo.com> | 2020-08-04 12:44:18 +0000 |
| commit | f8ab35f9e18d033cb9fa2b28c6abe3689afc774a (patch) | |
| tree | f6d91f29fe936bf4291d945b9e6147f3a40947c6 /addons/web/static | |
| parent | 918ccf5b0eb6b8e6f8d789f204bc3ce4134b797f (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')
| -rw-r--r-- | addons/web/static/src/js/model.js | 111 |
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 */ |
