Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Backbone/Marionette - How to listen to events on Region's child view?

I have a View, a CollectionView is rendered inside a region of this View. How do I make View listen to events of CollectionView?

const ChildCollectionView = marionette.CollectionView.extend({
    // ...

    events: {
        'click .bar': 'clickBar',
    },

    clickBar() {
        this.trigger('clickBar');
    },
}); 

const ParentView = marionette.View.extend({
    // ...
    regions: {
        foo: '.foo',
    },
    // ...
    onRender() {
        const fooRegion = this.getRegion('foo');

        fooRegion.on('show', function(view) {
            // XXX: this does not work
            view.on('childview:clickBar', function() {
                console.log('click bar');
            });
        });

        fooRegion.show(new ChildCollectionView({
            // ...
        }))
    },
});
like image 363
kkkkkkk Avatar asked Aug 29 '17 15:08

kkkkkkk


1 Answers

Looks like you're using Marionette 3.x. In short, you can use childViewEvents.

As to the specifics of your code, it would be better to have the childView of your CollectionView define the click event, as the listener to the child view event will receive the childView that was clicked. It would also be better to use the showChildView method in the ParentView's onRender.

const ChildView = marionette.View.extend({
    // ...
    triggers: {
        'click .bar': 'click:bar',
    },
    // or
    events: {
        'click .bar': 'clickBar'
    },
    clickBar() {
        // other child view stuff
        this.trigger('click:bar');
    },
});
const ChildCollectionView = marionette.View.extend({
    // ...
    childView: ChildView,
    childViewEvents: {
        'click:bar': 'barClicked',
    },
    barClicked(childView) {
        // other view stuff
        this.trigger('child:clicked:bar', childView);
        // or
        this.triggerMethod('child:clicked:bar', this, childView)
    }
});
const ParentView = marionette.View.extend({
    regions: {
        foo: '.foo'
    },
    childViewEvents: {
        'child:clicked:bar': 'clickBar'
    },
    clickBar(collectionChild, clickedChild) {
        console.log('click bar', collectionChild.cid, clickedChild.model.cid);
    },
    onRender() {
        this.showChildView('foo', new ChildCollectionView());
    }
});

See JSFiddle below for different ways to see an example plus a couple different ways to trigger events. (forked from Marionette example)

https://jsfiddle.net/opyfvsfx/36/

like image 87
Grafpaper10 Avatar answered Oct 31 '22 11:10

Grafpaper10