My goal I need to create a custom layout (a flow layout) that can receive a variable numbers of views and based on them, it creates regions as necessary and within those regions it shows the views that are passed in. The views can be arranged vertically or horizontally.
Requirement
The layout has a template where initially regions are not defined. It only contains a wrapper (data-role="region-wrapper"
) where added regions will be rendered.
My approach.
1 - Extend a Marionette.Layout
(obviously)
2 - Ovveride the construtor like the following
constructor: function(options) {
// call super here...
this.viewList= options.viewList || [];
this._defineRegions(); // see 3
}
3 - Define the regions dynamically
_defineRegions: function() {
_.each(this.viewList, function(view, index) {
var name = 'flowRegion_' + index;
var definition = { selector: "[data-region='flow-region-" + index + "']" };
this.addRegion(name, definition);
}, this);
},
4 - Render regions and views in onRender method within the same layout
onRender: function() {
_.each(this.viewList, function(view, index) {
// if the view has not been instantiated, instantiate it
// a region is a simple div element
var $regionEl = // creating a region element here based on the index
// append the region here
this.$el.find("[data-role='flow-wrapper']").append($regionEl);
var region = this.getRegion(index); // grab the correct region from this.regionManager
region.show(view);
}, this);
}
This solution seems working but I would like to know if I'm following a valid one or not. Any other approach to follow?
Maybe I'm not fully followed, but I can't see any reason a collectionView can't be used in this case.
The child views are all in same pattern, having data-region='flow-region-"
, and even have index
. This is an obvious pattern of collection and its view.
With collectionView you can do things similar, adding/removing child views, fully reset, close etc.
If this is the case I would definitely recommend to use CollectionView or CompositeView, instead of overriding Region here.
Update
About why removing a model will cause removing view.
Because Marionette CollectionView has such listener in constructor
:
this.listenTo(this.collection, "remove", this.removeItemView, this);
Add region in runtime.
It's totally legit though I have not done that before. Layout has prototype method addRegion(name, definition)
, so any instance of layout should be able to add/remove region/regions in runtime. The usage would be like this:
foo_layout.addRegion({region1: '#region-1'});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With