Search code examples
jquerybackbone.jsmarionette

Marionette - Region Manager required understanding


I am creating a app using, Marionettejs. It woks fine. but I confused with 'Layout' and 'Region Manager'. without using the Region Manager My view works fine. But how can i use the region Manager?

In my region I have 2 containers namely 'navi' and 'content' - when i render the navi i don't require the content. - is the time to play with region manager here?

if so ho can i do that? I came across with doc, But still I am not clear with this all.

any one detail me please?

here is my working example, please update the fiddle to see the result.

Demo

script:

var MenuView = Backbone.Marionette.ItemView.extend({
    template:_.template($('#menuTemp').html()),
    render:function(){
        this.$el.html(this.template());
        return this;
    }
});


//how can i use this?

var rm = new Marionette.RegionManager();
rm.addRegion("foo", "#bar");

//

container = new Backbone.Marionette.Region({
  el: "#container"
});

MyLayout = Backbone.Marionette.LayoutView.extend({
  template: "#my-layout",

  regions: {
    menu: "#menu",
    content: "#content"
  }
});

// Show the "layout" in the "container" region
layout = new MyLayout();
container.show(layout);
layout.removeRegion("content");

layout.menu.show(new MenuView().render()); //not working

Solution

  • Your layout will hold regions - you don't need to worry about region manager. So you could define a layout like this:

     class Show.Layout extends App.Views.Layout
      template: "surveys/show/show_layout"
    
      regions: 
        questionRegion: "#question-region"
        newRegion: "#new-region"
        panelRegion: "#panel-region"
        bannerRegion: "#banner-region"
    

    And you'd initialize/show it in your controller:

    class Show.Controller extends App.Controllers.Application
    
        initialize: (options) ->
          { survey, id } = options
          survey or= App.request "survey:entity", id
    
          App.execute "when:fetched", survey, =>
            @layout = @getLayoutView()
    
            @listenTo @layout, "show", =>
              @panelRegion survey
              @questionRegion survey
              @bannerRegion survey
    
            @show @layout
    
        questionRegion: (survey) ->
          App.request "show:survey:questions", survey, @layout.questionRegion
    
        panelRegion: (survey) ->
          panelView = @getPanelView survey
    
          @show panelView, region: @layout.panelRegion
    
        bannerRegion: (survey) ->
          bannerView = @getBannerView survey    
    
          @show bannerView, region: @layout.bannerRegion
    
        getLayoutView: ->
          new Show.Layout
    
        getBannerView: (survey) ->
          new Show.Banner
            model: survey
    
        getPanelView: (survey) ->
          new Show.Panel
            model: survey
    
        getQuestionView: (questions, survey) ->
          new Show.Questions
            collection: questions
            model: survey
    

    Basically you listen to the show method and when the layout is shown you show each of the regions.

    I do override the show method in my controllers:

      class Controllers.Application extends Marionette.Controller
    
        constructor: (options = {}) ->
          @region = options.region or App.request "default:region"
          super options
          @_instance_id = _.uniqueId("controller")
          App.execute "register:instance", @, @_instance_id
    
        close: ->
          App.execute "unregister:instance", @, @_instance_id
          super
    
        show: (view, options = {}) ->
          _.defaults options,
            loading: false
            region: @region
          view = if view.getMainView then view.getMainView() else view
          throw new Error("getMainView() did not return a view instance or #{view?.constructor?.name} is not a view instance") if not view
    
          @setMainView view
          @_manageView view, options
    
        getMainView: ->
          @_mainView
    
        setMainView: (view) ->
          return if @_mainView
          @_mainView = view
          @listenTo view, "close", @close
    
        _manageView: (view, options) ->
          if options.loading
            App.execute "show:loading", view, options
          else
            options.region.show view
    
        mergeDefaultsInto: (obj) ->
          obj = if _.isObject(obj) then obj else {}
          _.defaults obj, @_getDefaults()
    
        _getDefaults: ->
          _.clone _.result(@, "defaults")
    

    This is all patterned off of what I learned from backbonerails.com. He does a far better job explaining it than me :).