Search code examples
marionette

Marionette CompositeView -- Control Model Passed to ChildView


I have a view that I want to reuse in a CompositiveView, that reusable view need to be fed a model with an specific set of properties and each member of the collection passed to the CompositiveView has does properties but encapsulated in an inner object, like this:

{
    foo: "foo",
    bar: "bar"
    objWithStuffThatINeed: {
        ...
    }
}

The reusable view have to idea of this hierarchy and I can not change that view to make it aware of this. I was wondering if there is a way to pass only that objWithStuffThatINeed to the childView instead of the whole item in the current iteration of the collection.


Solution

  • You can change model of ItemView which use only fields you need.

    $(function() {
        // You reusable view.       
        var ExampleItemView = Backbone.Marionette.ItemView.extend({
            tagName: "li",
            template:  _.template('<%- baz%>'),
        });
        
        var ExampleCompositeView = Backbone.Marionette.CompositeView.extend({
        
            tagName: "ul",
            childView: ExampleItemView,
            template: _.template(''),
            
            buildChildView: function(child, ChildViewClass, childViewOptions) {
              // create the child view instance
              var view = new ChildViewClass( {
                model: new Backbone.Model(child.get('objWithStuffThatINeed'))
              });
              // return it
              return view;
            }
            
        });
        
        var testCollection = new Backbone.Collection(
          [{
              foo: 'foo1',
              bar: 'bar1',
              objWithStuffThatINeed: {
                baz: "baz1"
              }
          },
          {
              foo: 'foo2',
              bar: 'bar2',
              objWithStuffThatINeed: {
                baz: "baz2"
              }
          }
          ]
        );
        
        var region = new  Backbone.Marionette.Region({
          el: '.main-region'
        });
        
        region.show(new ExampleCompositeView({
          collection: testCollection
        }));
        
    });
    <!DOCTYPE html>
    <html>
    
      <head>
        <script data-require="jquery@*" data-semver="2.1.4" src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
        <script data-require="underscore.js@*" data-semver="1.8.3" src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
        <script data-require="backbone.js@*" data-semver="1.1.2" src="    //cdnjs.cloudflare.com/ajax/libs/backbone.js/1.1.2/backbone-min.js"></script>
        <script data-require="marionette.js@*" data-semver="2.2.2" src="http://cdnjs.cloudflare.com/ajax/libs/backbone.marionette/2.2.2/backbone.marionette.js"></script>
        <link rel="stylesheet" href="style.css" />
        <script src="script.js"></script>
      </head>
    
      <body>
        <div class="main-region"></div>
      </body>
    
    </html>