0
votes

Is it possible to dynamically add and remove regions to a layout with Marionette? My app needs to be able to push and pop regions from a layout. This is similar to how GitHub pushes and pops views when you drill down in the source code of a project. They have the slide over animation when presenting the next view and then it slides back when you're backing out. The idea is that I need to keep the previous views around. Another analogy would be how UINavigationControllers work on iOS.

Or maybe I should just define a custom layout that is able to handle adding and removing regions on the fly?

3
can you explain the scenario a little bit more? I'm not sure what you mean by "push" and "pop" in the context of a region. Perhaps some sample code of what you think it would look like, as well? Thanks.Derick Bailey
From the docs, "If you specify the same region name twice, the last one in wins." I wonder if Derick could comment on a way to do dynamic region naming on the fly...?Dane W
What do you mean by "dynamic region naming on the fly"?Derick Bailey
@DerickBailey see edits above.Andrew Young
@DerickBailey I think I misunderstood the question... my thought was that it might be useful for someone to be able to name their region something dynamically... b/c region names are keys in an object its not easy to make that key dynamic. Like I can't make a region by going myApp.addRegions({"itemRegion" + nextRegion : "#temp"} ); Instead it would have to be re-factored to call new regions like myApp.addRegions("regionName", "regionTemplate"); because the key is a key. I'm not sure there's any use case for it though b/c it doesn't solve his problem I don't think.Dane W

3 Answers

1
votes

I ended up implementing a container view to fit my needs. It cleans up event refs like you'd expect in Marionette.

https://github.com/ayoung/backbone-vs-marionette/blob/marionette/public/js/views/mainContainer.js

0
votes

I'm not sure but you may be getting confused with the existence of some html and the displaying of that html?

I mean you can make a CompositeView of Items and only show one of the items at a time. Then use jQuery animate or another animation library to move through the CompositeView's Items.

0
votes

Yes it is possible. Here is the code I use.

The layout:

var Layout = Marionette.LayoutView.extend({
    initialize: function(options) {
        options = _.extend({ regionTag: 'div' }, options);
        this.mergeOptions(options, ['regionTag', 'regionName']);
    },

    template: false,

    regions: {},

    append: function(view) {
        var viewClass = 'dynamic-layout-' + this.regionName,
            viewCount = $('.' + viewClass).length + 1,
            viewId = this.regionName + '-view-' + viewCount,
            $el = $('<' + this.regionTag + '/>', {
                id: viewId,
                class: viewClass
            });
        this.$el.append($el);

        var region = Marionette.Region.extend({
            el: '#' + viewId
        });

        this.regionManager.addRegion(viewId, region);
        this.regionManager.get(viewId).show(view);
    },

    appendEmpty: function(id, className, tag) {
        tag = tag || 'div';
        var data = { id: id, className: className, tag: tag };
        var $el = Marionette.Renderer.render('#append-layout-template', data);
        this.$el.append($el);
        var region = Marionette.Region.extend({
            el: '#' + id 
        });
        this.regionManager.addRegion(id, region);   
    },

    customRemove: function(regionId) {
        this.regionManager.removeRegion(regionId);
    }
});

A helpful template:

<script type="text/template" id="append-layout-template">
    <<%= tag %> id='<%= id %>' class='<%= className %>'></<%= tag %>>
</script>

The controller:

var view = new SomeView();
// the region name will be a part of a unique id
var layout = new Layout({ regionName: 'myRegion' });
// add a dynamic region to the layout and a view to that region
layout.append(view);
// same as above (you have to name the id and class yourself)
var regionId = 'myRegionId';
layout.appendEmpty(regionId, 'someClassName', 'span');
layout.getRegion(regionId).show(view);
// remove a region
layout.customRemove(regionId);