I have a Backbone view (InnerView
) that is rendered inside of another view (OuterView
). Both contain event handlers for the click
event, and event delegation is enabled (by default).
I would like InnerView
to append some data to the event before it propagates further. However, the code — as presented below — doesn't seem to affect e.data
at all, as it remains undefined afterwards:
var InnerView = Backbone.View.extend({
events: {
"click": "onClick"
},
render: function () {
// ...
},
onClick: function (e) {
e.data = e.data || {};
e.data.myData = 123;
console.log(e.data); // Object { myData: 123 }
}
});
var OuterView = Backbone.View.extend({
events: {
"click": "onClick"
},
render: function () {
// ...
this.$el.append(new InnerView);
// ...
},
onClick: function (e) {
console.log(e.data); // undefined
}
});
I tried stopping the event from propagating and then retriggering it with custom data (which would be stored in a somewhat different format, as I can't see a way to append data to the event object here):
// alternative version of InnerView#onClick()
onClick: function (e) {
e.stopImmediatePropagation();
this.trigger('click', {myData: 123});
}
But then OuterView
received no click event at all.
How do I deal with this problem? Note that I cannot trigger my event directly (or call a method, or set a property) on the destination view, as the two aren't exposed to each other (and that is why I've decided to utilize the event mechanism).
You can't use this.trigger()
because this is using Backbone's Events API and not jQuery's. You would need OuterView to listen for this event from InnerView, but, as you said, the views are not exposed to each other.
If you want to send data up the DOM, I think you are on the right track in turning to jQuery's trigger. However, I would trigger a custom event from InnerView:
onClick: function () {
this.$el.trigger('custom', {
myData: 123
});
}
This way, the click event propagation can proceed as normal and OuterView can listen specifically for the custom event:
events: {
"custom": "onCustom"
},
onCustom: function (e, data) {
console.log(data.myData); //123
}
Additionally, note the convenience of having your custom data passed as the second parameter to the event handler.