[FIX] pad: remove wrong warning at pad creation

When creating a pad before this change these were the steps:

- modify pad URL for new pad URL
- end of record loading

This caused an issue because modifying the record at this point would
mark it as dirty before displaying it (which would result in a erroneous
warning "The record has been modified, your changes will be discarded.
Are you sure you want to leave this page ?").

With this fix:

- modifying the pad URL is done after the record is ready

- deferred have been unified (to remove possible race conditions)

closes #15239
opw-702797

forward port note: this change is needed up to saas-15, over saas-15
only a small part is needed (because x2many views are loaded with the
root view and there is one widget instance per record).

code note: it would be better to modify load_record of form view and
delay `record_loaded` upto after x2many views are loaded, but possible
impacts have been judged too risky so this is done only in pad widget.
This commit is contained in:
Nicolas Lempereur
2017-04-26 18:32:18 +02:00
parent ec8699db17
commit cd2b07ea44
+45 -16
View File
@@ -17,7 +17,9 @@ var FieldPad = form_common.AbstractField.extend(form_common.ReinitializeWidgetMi
event.preventDefault();
self.set("configured", true);
});
this.pad_loading_request = null;
// CHANGES ONLY NEEDED UNTIL SAAS-15
// deferred for request getting pad content (readonly) or new pad url (edit)
this._pad_loading_deferred = null;
},
initialize_content: function() {
var self = this;
@@ -36,14 +38,25 @@ var FieldPad = form_common.AbstractField.extend(form_common.ReinitializeWidgetMi
},
render_value: function() {
var self = this;
$.when(this._configured_deferred, this.pad_loading_request).always(function() {
$.when(this._configured_deferred).always(function() {
if (!self.get('configured')){
return;
}
// reject previously ongoing _pad_loading_deferred
if (self._pad_loading_deferred !== null) {
self._pad_loading_deferred.reject();
self.$('.oe_pad_content').removeClass('oe_pad_loading').html('');
}
self._pad_loading_deferred = $.Deferred();
// keep reference to current _pad_loading_deferred
var loading_def = self._pad_loading_deferred;
var value = self.get('value');
if (self.get('effective_readonly')) {
if (_.str.startsWith(value, 'http')) {
self.pad_loading_request = self.view.dataset.call('pad_get_content', {url: value}).done(function(data) {
self.view.dataset.call('pad_get_content', {url: value}).then(loading_def.resolve, loading_def.reject);
loading_def.done(function(data) {
self.$('.oe_pad_content').removeClass('oe_pad_loading').html('<div class="oe_pad_readonly"><div>');
self.$('.oe_pad_readonly').html(data);
}).fail(function() {
@@ -54,21 +67,37 @@ var FieldPad = form_common.AbstractField.extend(form_common.ReinitializeWidgetMi
}
}
else {
var def = $.when();
var def = $.Deferred();
if (! value || !_.str.startsWith(value, 'http')) {
def = self.view.dataset.call('pad_generate_url', {
context: {
model: self.view.model,
field_name: self.name,
object_id: self.view.datarecord.id
},
}).then(function(data) {
if (! data.url) {
self.set("configured", false);
} else {
self.internal_set_value(data.url);
}
var deferreds = [
self.view.dataset.call('pad_generate_url', {
context: {
model: self.view.model,
field_name: self.name,
object_id: self.view.datarecord.id
}
}),
// change record only after record_loaded and its call stack is finished
self.view.record_loaded.then(function() {
var call_stack_ended = $.Deferred();
_.defer(call_stack_ended.resolve);
return call_stack_ended;
})
];
// delay onchange after x2many views are loaded
deferreds = deferreds.concat(_.compact(_.pluck(self.view.fields, 'is_loaded')));
$.when.apply($, deferreds).then(function(data) {
// update value only if loading_def has not been previously rejected
loading_def.resolve().done(function(){
if (! data.url) {
self.set("configured", false);
} else {
self.internal_set_value(data.url);
}
}).then(def.resolve, def.reject);
});
} else {
def.resolve();
}
def.then(function() {
value = self.get('value');