[FIX] web: form: prevent from calling mounted twice

With this commit, the FormRenderer no longer directly extends
the WidgetAdapterMixin. It doesn't need to as its parent class
(the BasicRenderer) already uses it. Worse, they both called
WidgetAdapterMixin.on_attach_callback, and thus mounted
was called twice on Components in form views.

closes odoo/odoo#55401

X-original-commit: 4c627abd310a131a4828e9ee6be451aeee4708db
Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
This commit is contained in:
Michael Mattiello (mcm)
2020-08-05 11:54:42 +00:00
parent f1bbc282f8
commit faab9ee9f6
2 changed files with 30 additions and 11 deletions
@@ -5,7 +5,6 @@ var BasicRenderer = require('web.BasicRenderer');
var config = require('web.config');
var core = require('web.core');
var dom = require('web.dom');
const { WidgetAdapterMixin } = require('web.OwlCompatibility');
var viewUtils = require('web.viewUtils');
var _t = core._t;
@@ -14,7 +13,7 @@ var qweb = core.qweb;
// symbol used as key to set the <field> node id on its widget
const symbol = Symbol('form');
var FormRenderer = BasicRenderer.extend(WidgetAdapterMixin, {
var FormRenderer = BasicRenderer.extend({
className: "o_form_view",
events: _.extend({}, BasicRenderer.prototype.events, {
'click .o_notification_box .oe_field_translate': '_onTranslate',
@@ -53,18 +52,10 @@ var FormRenderer = BasicRenderer.extend(WidgetAdapterMixin, {
this._applyFormSizeClass();
return this._super.apply(this, arguments);
},
/**
* @override
*/
destroy() {
this._super(...arguments);
WidgetAdapterMixin.destroy.call(this);
},
/**
* Called each time the form view is attached into the DOM
*/
on_attach_callback: function () {
WidgetAdapterMixin.on_attach_callback.call(this);
this._isInDom = true;
_.invoke(this.widgets, 'on_attach_callback');
this._super.apply(this, arguments);
@@ -73,7 +64,6 @@ var FormRenderer = BasicRenderer.extend(WidgetAdapterMixin, {
* Called each time the renderer is detached from the DOM.
*/
on_detach_callback: function () {
WidgetAdapterMixin.on_detach_callback.call(this);
this._isInDom = false;
this._super.apply(this, arguments);
},
@@ -6,6 +6,7 @@ var BasicModel = require('web.BasicModel');
var concurrency = require('web.concurrency');
var core = require('web.core');
var fieldRegistry = require('web.field_registry');
const fieldRegistryOwl = require('web.field_registry_owl');
var FormView = require('web.FormView');
var mixins = require('web.mixins');
var NotificationService = require('web.NotificationService');
@@ -9532,6 +9533,34 @@ QUnit.module('Views', {
form.destroy();
delete widgetRegistry.map.test;
});
QUnit.test('do not call mounted twice on children', async function (assert) {
assert.expect(3);
class CustomFieldComponent extends fieldRegistryOwl.get('boolean') {
mounted() {
super.mounted(...arguments);
assert.step('mounted');
}
willUnmount() {
super.willUnmount(...arguments);
assert.step('willUnmount');
}
}
fieldRegistryOwl.add('custom', CustomFieldComponent);
const form = await createView({
View: FormView,
model: 'partner',
data: this.data,
arch: `<form><field name="bar" widget="custom"/></form>`,
});
form.destroy();
delete fieldRegistryOwl.map.custom;
assert.verifySteps(['mounted', 'willUnmount']);
});
});
});