Symba Symba - 3 months ago 24
Javascript Question

itemView trigger a custom event reaching the parrent

I have this code
http://jsfiddle.net/QRcF5/2/

$(function() {
var Header = Backbone.Marionette.ItemView.extend({
template: _.template('<h4>TEST</h4><button>EDIT</button>'),

tagName: 'nav',

triggers: {
'click button': 'btn_clicked'
}
}),
Layout = Backbone.Marionette.Layout.extend({
template: _.template('<header></header>'),

regions: {
header: 'header'
},

events: {
'itemview:btn_clicked': 'clicked'
},

clicked: function() {
alert('Ana are mere');
}
});

layout = new Layout();
$('body').append(layout.render().el);
layout.header.show(new Header());
});


I'm using a layout with one ItemView (later I want a more complex nesting) and want to capture in LAYOUT the event that is happening in the ITEMVIEW. It seems its not bubbling upwards or I'm doing something wrong here.




UPDATE 1
I've tried events, triggers (for the child) and on, events (for the parent) but I still can't get the event caught inside the parent.

I can use:

_.extend(App.vent, Backbone.Events);

Backbone.Marionette.ItemView.extend({
....
App.vent.trigger('btn_clicked');
....
});

Backbone.Marionette.Layout.extend({
....
App.vent.on('btn_clicked', function() { doCoding(); });
....
});


But this way I'm breaking the encapsulation. Is there a way to keep the encapsulation by using Marionette triggers eventing and keep it all in the layout and not polluting the entire app ?




UPDATE 2

http://jsfiddle.net/QRcF5/5/

I've update the jsfiddle to use the _.extend(vent, Backbone.Events). If anyone has a better pattern for this, please let us know :D

Answer

I've found the solution (buried somewhere in the documentation making some connections between layout, region and view) !

http://jsfiddle.net/QRcF5/6/


In the context of communication ONLY between the the parent (layout) and the child (itemView):

1) the child triggers the custom event (opposed to vent extend Backbone.Events - it only speaks to those who have access to it = encapsulation)

triggers: {
    'click button': 'custom_event:btn_clicked'
}


2) the parent listen to this event having access to the child with the on('show',....)

initialize: function() {
    var that = this; // needed for the listenTo which overrides 'THIS'

    this.header.on('show', function(view) {
        this.listenTo(view, 'custom_event:btn_clicked', that.clicked);
    });
},


Example:

layout = new Layout();
$('body').append(layout.render().el);
layout.header.show(new Header()); // Here we get access to child and its events


The (hidden) power of Marionette. (I mean when I say hidden, because being relatively new, the documentation is barebone and the complex examples are scarce).

With little perseverance anything can be accomplished.

Comments