summaryrefslogtreecommitdiff
path: root/addons/web/static/src/js/fields/basic_fields.js
diff options
context:
space:
mode:
authorAaron Bohy <aab@odoo.com>2017-05-19 10:13:24 +0200
committerAaron Bohy <aab@odoo.com>2017-05-19 15:51:57 +0200
commitc929a81e8f015f9234f68749a29fe6a9c21577b6 (patch)
tree4471550e5f2c70ffe75137d3fc272f97a8e25ef8 /addons/web/static/src/js/fields/basic_fields.js
parenta845ecffa13657922ba75dbc7f37c7bad8c0e4c0 (diff)
[FIX] web: DebounceField: do nothing after widget destruction
DebounceFields debounce the function that notify field changes to their environment (using _.debounce). It may happen that this function is called once the field widget is destroyed (e.g. type something in a char field and quickly click on Save, the function is called directly by _commitChanges, but the debounced call is still pending). It may be a problem if the subsequent code does something like this.getSession().some_key, as if the widget is destroyed, it has no parent that can provide it the session, and thus it crashes. Also rename attribute _debouncedStarted into _isDirty as it makes much more sense.
Diffstat (limited to 'addons/web/static/src/js/fields/basic_fields.js')
-rw-r--r--addons/web/static/src/js/fields/basic_fields.js16
1 files changed, 11 insertions, 5 deletions
diff --git a/addons/web/static/src/js/fields/basic_fields.js b/addons/web/static/src/js/fields/basic_fields.js
index b35b84fe6ee..3f279eeeec7 100644
--- a/addons/web/static/src/js/fields/basic_fields.js
+++ b/addons/web/static/src/js/fields/basic_fields.js
@@ -83,10 +83,10 @@ var DebouncedField = AbstractField.extend({
init: function () {
this._super.apply(this, arguments);
- // _debouncedStarted is used to detect that the user interacted at least
+ // _isDirty is used to detect that the user interacted at least
// once with the widget, so that we can prevent it from triggering a
// field_changed in commitChanges if the user didn't change anything
- this._debouncedStarted = false;
+ this._isDirty = false;
if (this.mode === 'edit') {
if (this.DEBOUNCE) {
this._doDebouncedAction = _.debounce(this._doAction, this.DEBOUNCE);
@@ -97,7 +97,7 @@ var DebouncedField = AbstractField.extend({
var self = this;
var debouncedFunction = this._doDebouncedAction;
this._doDebouncedAction = function () {
- self._debouncedStarted = true;
+ self._isDirty = true;
debouncedFunction.apply(self, arguments);
};
}
@@ -115,7 +115,7 @@ var DebouncedField = AbstractField.extend({
* @override
*/
commitChanges: function () {
- if (this._debouncedStarted && this.mode === 'edit') {
+ if (this._isDirty && this.mode === 'edit') {
this._doAction();
}
},
@@ -132,7 +132,13 @@ var DebouncedField = AbstractField.extend({
* @private
*/
_doAction: function () {
- this._setValue(this._getValue());
+ // as _doAction may be debounced, it may happen that it is called after
+ // the widget has been destroyed, and in this case, we don't want it to
+ // do anything (commitChanges ensures that if it has local changes, they
+ // are triggered up before the widget is destroyed, if necessary).
+ if (!this.isDestroyed()) {
+ this._setValue(this._getValue());
+ }
},
/**
* Should return the current value of the field, in the DOM (for example,