[FIX] synchronization of o2m widget saving, avoid race condition when clicking on button of unsaved record

After saving, the formview would both refresh the form and lauch the
action itself, which launches a refresh of its own.

Issue is that o2m's filling of themselves (a read) is async and
triggered by the set_value on the o2m field, so the second reload of
the form would be interspersed (between the first reload and the end
of the o2ms loading), resulting in corrupted state for the o2ms if the
button's action somehow changed the contents of the o2m (it would
remove the old records and return brand new ids during the refresh):
the set_value on the o2m would empty the o2m's dataset cache, and the
returning fetch request would try to find in cache values removed from
it, or something, blowing up everything.

Anyway, this was fixed by ensuring the button action is only executed
after the form is completely done doing its post-save reload (using
the new async set_value). This is a tiny bit brittle in that onchanges
are synchronous but call set_value, so a set_value on an o2m from an
onchange may have issues. It also increases the flicker of the view,
as the o2m is reloaded twice in quick succession.

lp bug: https://launchpad.net/bugs/885658 fixed

bzr revid: xmo@openerp.com-20111117161426-72jzhvv3dm387uom
This commit is contained in:
Xavier Morel 2011-11-17 17:14:26 +01:00
parent 6bd9084740
commit 7c629a31cc
1 changed files with 5 additions and 5 deletions

View File

@ -487,8 +487,8 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
// should not happen in the server, but may happen for internal purpose
return $.Deferred().reject();
} else {
this.reload();
return $.when(r).then(success);
return $.when(this.reload()).pipe(function () {
return $.when(r).then(success); }, null);
}
},
/**
@ -2120,7 +2120,7 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
},
reload_current_view: function() {
var self = this;
self.is_loaded = self.is_loaded.pipe(function() {
return self.is_loaded = self.is_loaded.pipe(function() {
var view = self.viewmanager.views[self.viewmanager.active_view].controller;
if(self.viewmanager.active_view === "list") {
return view.reload_content();
@ -2193,8 +2193,8 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
if (this.dataset.index === null && this.dataset.ids.length > 0) {
this.dataset.index = 0;
}
self.reload_current_view();
this.is_setted.resolve();
self.is_setted.resolve();
return self.reload_current_view();
},
get_value: function() {
var self = this;