diff --git a/addons/web/static/src/js/views/abstract_controller.js b/addons/web/static/src/js/views/abstract_controller.js index 780b0bcf1b6..70cec99aa86 100644 --- a/addons/web/static/src/js/views/abstract_controller.js +++ b/addons/web/static/src/js/views/abstract_controller.js @@ -287,7 +287,7 @@ var AbstractController = mvc.Controller.extend(ActionMixin, { self.handle = handle || self.handle; // update handle if we reloaded var state = self.model.get(self.handle); var localState = self.renderer.getLocalState(); - return self.dp.add(self.renderer.updateState(state, params)).then(function () { + return self.dp.add(self.updateRendererState(state, params)).then(function () { if (self._controlPanel && cpUpdateIndex !== self._controlPanel.updateIndex) { return; } @@ -297,6 +297,18 @@ var AbstractController = mvc.Controller.extend(ActionMixin, { }); }, + /** + * Update the state of the renderer. + * This method is required to be overridden in OWL components through the controller + * adapter + * + * @param {Object} state the model state + * @param {Object} params will be given to the model and to the renderer + */ + updateRendererState: function(state, params) { + return this.renderer.updateState(state, params); + }, + //-------------------------------------------------------------------------- // Private //-------------------------------------------------------------------------- diff --git a/addons/web/static/src/js/views/abstract_renderer_owl.js b/addons/web/static/src/js/views/abstract_renderer_owl.js new file mode 100644 index 00000000000..6071d410d4a --- /dev/null +++ b/addons/web/static/src/js/views/abstract_renderer_owl.js @@ -0,0 +1,8 @@ +odoo.define('web.AbstractRendererOwl', function (require) { + "use strict"; + + class AbstractRenderer extends owl.Component { } + + return AbstractRenderer; + +}); diff --git a/addons/web/static/src/js/views/controller_adapter.js b/addons/web/static/src/js/views/controller_adapter.js new file mode 100644 index 00000000000..17973cd3b54 --- /dev/null +++ b/addons/web/static/src/js/views/controller_adapter.js @@ -0,0 +1,42 @@ +odoo.define('web.ControllerAdapter', function (require) { +"use strict"; + +var AbstractController = require('web.AbstractController'); + +var ControllerAdapter = AbstractController.extend({ + on_attach_callback: function () { + this.renderer.__callMounted(); + }, + on_detach_callback: function () { + this.renderer.__callWillUnmount(); + }, + + /** + * @override + * */ + updateRendererState: async function (props) { + let prom; + this.renderer.updateProps(props); + if (this.renderer.__owl__.isMounted) { + prom = this.renderer.render(); + } else { + prom = this.renderer.mount(this.$('.o_content')[0], true); + } + return prom; + }, + + //-------------------------------------------------------------------------- + // Private + //-------------------------------------------------------------------------- + /** + * @override + * @private + */ + _startRenderer: async function () { + return this.renderer.mount(this.$('.o_content')[0]); + }, +}); + +return ControllerAdapter; + +}); diff --git a/addons/web/static/src/js/views/renderer_wrapper.js b/addons/web/static/src/js/views/renderer_wrapper.js new file mode 100644 index 00000000000..7c1c5d6b273 --- /dev/null +++ b/addons/web/static/src/js/views/renderer_wrapper.js @@ -0,0 +1,57 @@ +odoo.define('web.RendererWrapper', function (require) { + "use strict"; + + const { xml } = owl.tags; + const AbstractRenderer = require('web.AbstractRendererOwl'); + + class RendererWrapper extends owl.Component { + /** + * + * @param {Object} parent + * @param {Object} props + * @param {Class} concreteRenderer + */ + constructor(parent, props, concreteRenderer) { + super(...arguments); + this.concreteRenderer = concreteRenderer; + this.data = props; + } + + /** + * Update the props of the renderer before a re-render + * called on the initial render as well as when the renderer is re-mounted (view switched) + * + * @param {Object} props new props + */ + updateProps(props) { + this.data = Object.assign(this.data || {}, props); + } + + mounted() { + for (let x in this.__owl__.children) { + this.__owl__.children[x].__callMounted(); + } + } + + willUnmount() { + for (let x in this.__owl__.children) { + this.__owl__.children[x].__callWillUnmount(); + } + } + + setParent() { } + + getLocalState() { } + + setLocalState() { } + + giveFocus() { } + }; + + RendererWrapper.template = xml``; + + RendererWrapper.components = { AbstractRenderer }; + + return RendererWrapper; + +}); diff --git a/addons/web/views/webclient_templates.xml b/addons/web/views/webclient_templates.xml index 8050d18341a..a9f05f97891 100644 --- a/addons/web/views/webclient_templates.xml +++ b/addons/web/views/webclient_templates.xml @@ -298,8 +298,11 @@ + + +