summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Bohy <aab@odoo.com>2017-03-01 14:59:59 +0100
committerAaron Bohy <aab@odoo.com>2017-04-11 19:44:38 +0200
commitc5cf445462f43222a1982b613bd532018d6cad8e (patch)
treed6cd0bc5c2ec5f2c8882768f326cb8ffd2b47794
parent3ff7ff3e94e4fe34ec09a45fda04f0c8de33cd32 (diff)
[FIX] web: Form: protect against widget destruction
When a button is clicked in a form view, the event 'execute_action' is triggered up and catched by the view_manager, which can do various async stuff. Meanwhile, the form view might be destroyed, and in this case, the handlers shouldn't be executed when the async stuff is done.
-rw-r--r--addons/web/static/src/js/views/form/form_controller.js11
-rw-r--r--addons/web/static/test/views/form_tests.js21
2 files changed, 29 insertions, 3 deletions
diff --git a/addons/web/static/src/js/views/form/form_controller.js b/addons/web/static/src/js/views/form/form_controller.js
index 498fb29453b..ceefd59d3c8 100644
--- a/addons/web/static/src/js/views/form/form_controller.js
+++ b/addons/web/static/src/js/views/form/form_controller.js
@@ -266,6 +266,11 @@ var FormController = BasicController.extend({
_callButtonAction: function (attrs, record) {
var self = this;
var def = $.Deferred();
+ var reload = function () {
+ if (!self.isDestroyed()) {
+ self.reload();
+ }
+ };
record = record || this.model.get(this.handle);
var recordID = record.data.id;
this.trigger_up('execute_action', {
@@ -276,13 +281,13 @@ var FormController = BasicController.extend({
record_id: recordID,
on_closed: function (reason) {
if (!_.isObject(reason)) {
- return self.reload();
+ reload();
}
},
- on_fail: this.reload.bind(this),
+ on_fail: reload,
on_success: def.resolve.bind(def),
});
- return def;
+ return this.alive(def);
},
/**
* @override method from FieldManagerMixin
diff --git a/addons/web/static/test/views/form_tests.js b/addons/web/static/test/views/form_tests.js
index 40ea74f8890..2662313de8b 100644
--- a/addons/web/static/test/views/form_tests.js
+++ b/addons/web/static/test/views/form_tests.js
@@ -2161,6 +2161,27 @@ QUnit.module('Views', {
}
});
+ QUnit.test('rpc complete after destroying parent', function (assert) {
+ // We just test that there is no crash in this situation
+ assert.expect(0);
+ var form = createView({
+ View: FormView,
+ model: 'partner',
+ data: this.data,
+ arch: '<form>' +
+ '<button name="update_module" type="object" class="o_form_button_update"/>' +
+ '</form>',
+ res_id: 2,
+ intercepts: {
+ execute_action: function (event) {
+ form.destroy();
+ event.data.on_success();
+ }
+ }
+ });
+ form.$('.o_form_button_update').click();
+ });
+
QUnit.test('onchanges that complete after discarding', function (assert) {
assert.expect(4);