3
votes

I'm using a CompositeView to create a grid of images that they had some events on it. This is how it looks like:

Backbone.Marionette.CompositeView.extend({

    events: {
        'click li.feed-thumb': 'clickElement',
    },

    template: _.template(template),

    itemView: ItemFeedView,
    itemViewContainer: "#feed ul.feed",

    clickElement: function(event) { 
        var profile = new ProfileFeedView();

    }
});

My template for this CompositeView contains a <li> element that will render the profile when I click on a image. I use the same <li> for all the events of click into a image. I would like to handle this as a region, because I understand that doing it as region Marionette will handle the opening and closing of the views.

I think CompositeView do not support a regions: {profileRegion: '#feed-profile'}, what's my options?

Thanks in advance!

3

3 Answers

4
votes

You should use a Layout View in which you can specify as many regions as you want, so you can create a list region in which you can put your composite view and a profile region in which you can put a item view that will render the profile.

Marionette's docs -- Layout View

3
votes

If for some reason you want to have regions in your CompositeView you can also do something like this:

var YourView = Backbone.Marionette.CompositeView.extend({
    regions: {
       "someRegion": ".someRegionClass"
    },
    "initialize": function(options) {
       this._initializeRegions(options);
    },
    "onDestroy": function() {
       this.regionManager.destroy();
    }
})
_.each(["_initializeRegions", "_initRegionManager",
        "_buildRegions", "addRegion", "addRegions",
        "removeRegion", "getRegion", "getRegions",
        "_reInitializeRegions", "getRegionManager"], function(prop) {
    PaginatorView.prototype[prop] = Marionette.LayoutView.prototype[prop];
});

To be honest, it works but i haven't tested it for full functionality.

view.someRegion.show(otherView) works.

(also works for other views i guess and you will have to add your other options needed to extend the view of course)

0
votes

In addition to what Manfred said I implemented it this way on a Marionette Composite View:

View.ListView = Marionette.CompositeView.extend({
    template: listTpl,
    emptyView: noItemsTpl,
    childView: View.ListItem,
    childViewContainer: '#items-list',

    regions: {
       "someRegion": "#someRegion"
    },

    initialize: function(options) {
        //give this composite view a LayoutView behaviour with added region manager
        this.regionManager = new Marionette.RegionManager();
        _.each(["_initializeRegions", "_initRegionManager",
                "_buildRegions", "addRegion", "addRegions",
                "removeRegion", "getRegion", "getRegions",
                "_reInitializeRegions", "getRegionManager"], function(prop) {
            Marionette.CompositeView.prototype[prop] = Marionette.LayoutView.prototype[prop];
        });
        var that = this;
        _.each(this.regions, function(value, key) {
            var region = that.addRegion(key, value);
            that[key] = region;
        });
    },

    onDestroy: function() {
       this.regionManager.destroy();
    }
});

This way you will be able to interact with your CompositeView instance the exact same way you do with a LayoutView instance:

var listView = new View.ListView({ ... });
var anotherView = new View.AnotherView({ ... });
listView.someRegion.show(anotherView);