9

I have a layout, but cannot define all of its regions in advance because they are not known.

So later on an ItemView is created and I'd like to create a new region in the layout using the view's ID as the region's name so I can then say:

layout.dynamicRegionName.show(newItemView);

But there is cyclic dependency here.

  1. I haven't rendered the view yet, so I cannot make a reference to its DOM element to be used in the layout's call to .addRegion()

  2. I cannot render it, precisely because I want it to get attached to the DOM tree through the dynamically added region by calling its .show()

@DerickBailey In the Marionette.Layout docs in github I believe there is an error in the example that has: layout.show(new MenuView());

but technically this is close to what we'd need here i.e. to be able to do:

layout.addRegion(VAR_WITH_NEW_REGION_NAME, aViewInstance);

and have this add a new Region into the layout rendering inside it directly the view instance.

Am I missing some other obvious way to achieve this? Is that a known missing functionality? Is there a reason not to have it?

I'm aware of this previous Q: "Dynamically add/remove regions to a layout" but don't see any clear/definite answer to it.

Community
  • 1
  • 1
Thalis K.
  • 7,363
  • 6
  • 39
  • 54

2 Answers2

19

Marionette v1.0 (v1.0.2 is latest, right now) supports dynamic regions in Layouts.


var MyLayout = Marionette.Layout.extend({
  template: "#some-template"
});

var layout = new MyLayout();
layout.render();

layout.addRegion("someRegion", "#some-element");

layout.someRegion.show(new MyView());
Derick Bailey
  • 72,004
  • 22
  • 206
  • 219
  • 2
    Helpful answer. My question is the following. Does the element (#some-element) need to be within the template or not? In other words, does the template contains that element or the addRegion method appends it for me? See my question for this http://stackoverflow.com/questions/20570284/creating-a-layout-that-accepts-a-variable-number-of-views-and-hence-regions – Lorenzo B Dec 13 '13 at 18:20
  • Yes, the template has to contain the el. So addRegion is kind of weird :-/ – yves amsellem Apr 10 '14 at 12:37
  • Not really 'weird' as such. A region is a container that just wraps around a given element. Likewise when you remove a region it won't remove the DOM element, just the region object. – backdesk Jul 03 '14 at 08:27
  • 4
    @backdesk I understand it's meant to work that way but just because it's an intended feature by the author doesn't mean it's not weird from an end-user point of view. It does feel weird that I still need to have a wrapper el in order to "add Region". I came to this question after googling "dynamic marionette region" hoping I would be able to have a single empty root element to which various regions could be attached. That's what people think normally when they hear "dynamic". To me it sounds pretty static. – Vlad Nov 23 '15 at 17:46
0

In one of my projects, I faced a similar issue. I needed to create a form dynamically, i.e the form would contain different field views that could not be determined prior runtime. I needed the fields to be Marionette views because they had pretty complicated behaviour.

The way I have done it in Marionette 1.4 in CoffeeScript:

  class Module.AdditionalOptionsLayout extends Marionette.Layout
    tagName: 'form'

    initialize: (options = {}) ->
      @_fieldViews = options.fieldViews || []

    onRender: ->
      @_showFields @_fieldViews

    _showFields: (fieldViews) ->
      fieldViews.forEach (fieldView) => @_addRegion().show fieldView

    _addRegion: ->
      regionClass = _.uniqueId('field-region__')
      @$el.append $("<div class=\"#{regionClass}\"></div>")
      @addRegion regionClass, '.' + regionClass

Please, let me know if it needs further explanation or I can clarify this in JS. I am also aware that it is a late answer, however, hope somebody could find it still useful. Also, note - the answer is relevant only for Marionette 1.x