0

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?

Andrew Young
  • 1,779
  • 1
  • 13
  • 27
  • 1
    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 Oct 13 '12 at 01:11
  • 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 Oct 13 '12 at 04:07
  • What do you mean by "dynamic region naming on the fly"? – Derick Bailey Oct 13 '12 at 17:36
  • @DerickBailey see edits above. – Andrew Young Oct 15 '12 at 17:38
  • @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 Oct 17 '12 at 00:27

3 Answers3

1

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

Andrew Young
  • 1,779
  • 1
  • 13
  • 27
0

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.

Dane W
  • 408
  • 4
  • 14
0

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);
galki
  • 8,149
  • 7
  • 50
  • 62