[IMP] web: add Odoo view compatibility for OWL

Add a base class for a complete OWL renderer
Add a compatibility layer for a Odoo controller that uses a OWL renderer.

Co-authored-by: Pierre Rousseau <pro@odoo.com>
This commit is contained in:
Vincent Schippefilt
2019-12-09 11:09:10 +00:00
co-authored by Pierre Rousseau
parent 2cfa68b571
commit d06e67e748
5 changed files with 123 additions and 1 deletions
@@ -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
//--------------------------------------------------------------------------
@@ -0,0 +1,8 @@
odoo.define('web.AbstractRendererOwl', function (require) {
"use strict";
class AbstractRenderer extends owl.Component { }
return AbstractRenderer;
});
@@ -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;
});
@@ -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`<t t-component="concreteRenderer" t-props="data"/>`;
RendererWrapper.components = { AbstractRenderer };
return RendererWrapper;
});
+3
View File
@@ -298,8 +298,11 @@
<script type="text/javascript" src="/web/static/src/js/views/abstract_view.js"></script>
<script type="text/javascript" src="/web/static/src/js/views/abstract_renderer.js"></script>
<script type="text/javascript" src="/web/static/src/js/views/abstract_renderer_owl.js"></script>
<script type="text/javascript" src="/web/static/src/js/views/abstract_model.js"></script>
<script type="text/javascript" src="/web/static/src/js/views/abstract_controller.js"></script>
<script type="text/javascript" src="/web/static/src/js/views/controller_adapter.js"></script>
<script type="text/javascript" src="/web/static/src/js/views/renderer_wrapper.js"></script>
<script type="text/javascript" src="/web/static/src/js/views/basic/basic_model.js"></script>
<script type="text/javascript" src="/web/static/src/js/views/basic/basic_view.js"></script>
<script type="text/javascript" src="/web/static/src/js/views/basic/basic_controller.js"></script>