[IMP] web: introduces event bubbling in widgets
This commit adds event bubbling in the event dispatcher mixin (which inherits from parentedmixins). To do this, it introduces a new small class 'OdooEvent', which register the target and if the event is stopped. Also, widgets have a new 'custom_events' dictionary to easily register callbacks like the event dictionary.
This commit is contained in:
committed by
Aaron Bohy
parent
97a5eee0ac
commit
a9522cb46f
@@ -114,6 +114,22 @@ var ParentedMixin = {
|
||||
},
|
||||
};
|
||||
|
||||
function OdooEvent (target, name, data) {
|
||||
this.target = target;
|
||||
this.name = name;
|
||||
this.data = Object.create(null);
|
||||
_.extend(this.data, data);
|
||||
this.stopped = false;
|
||||
}
|
||||
|
||||
OdooEvent.prototype.stop_propagation = function () {
|
||||
this.stopped = true;
|
||||
};
|
||||
|
||||
OdooEvent.prototype.is_stopped = function () {
|
||||
return this.stopped;
|
||||
};
|
||||
|
||||
/**
|
||||
* Backbone's events. Do not ever use it directly, use EventDispatcherMixin instead.
|
||||
*
|
||||
@@ -256,6 +272,16 @@ var EventDispatcherMixin = _.extend({}, ParentedMixin, {
|
||||
this.__edispatcherEvents.trigger.apply(this.__edispatcherEvents, arguments);
|
||||
return this;
|
||||
},
|
||||
trigger_up: function(name, info) {
|
||||
var event = new OdooEvent(this, name, info);
|
||||
this._trigger_up(event);
|
||||
},
|
||||
_trigger_up: function(event) {
|
||||
this.__edispatcherEvents.trigger(event.name, event);
|
||||
if (!event.is_stopped() && (parent = this.getParent())) {
|
||||
parent._trigger_up(event);
|
||||
}
|
||||
},
|
||||
destroy: function() {
|
||||
var self = this;
|
||||
_.each(this.__edispatcherRegisteredEvents, function(event) {
|
||||
|
||||
@@ -64,6 +64,7 @@ var Widget = core.Class.extend(mixins.PropertiesMixin, {
|
||||
className: null,
|
||||
attributes: {},
|
||||
events: {},
|
||||
custom_events: {},
|
||||
/**
|
||||
* The name of the QWeb template that will be used for rendering. Must be
|
||||
* redefined in subclasses or the default render() method can not be used.
|
||||
@@ -94,6 +95,7 @@ var Widget = core.Class.extend(mixins.PropertiesMixin, {
|
||||
}
|
||||
// FIXME: this should not be
|
||||
this.setElement(this._make_descriptive());
|
||||
this.delegateCustomEvents();
|
||||
},
|
||||
/**
|
||||
* Method called between init and start. Performs asynchronous calls required by start.
|
||||
@@ -303,6 +305,21 @@ var Widget = core.Class.extend(mixins.PropertiesMixin, {
|
||||
}
|
||||
}
|
||||
},
|
||||
delegateCustomEvents: function () {
|
||||
if (_.isEmpty(this.custom_events)) { return; }
|
||||
for (var key in this.custom_events) {
|
||||
if (!this.custom_events.hasOwnProperty(key)) { continue; }
|
||||
|
||||
var method = this.proxy(this.custom_events[key]);
|
||||
this.on(key, this, wrap_handler(method));
|
||||
}
|
||||
function wrap_handler(callback) {
|
||||
return function (event) {
|
||||
event.stop_propagation();
|
||||
callback(event);
|
||||
};
|
||||
}
|
||||
},
|
||||
undelegateEvents: function () {
|
||||
this.$el.off('.widget_events');
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user