Pergunta

We have to display the following view:

Categories (displayed as tables), each category table should have products (tr).

How can we structure it using Marionette itemView and CompositeView?

We need the product to be an itemView.

Should we make each category as CompositeView, and have more than one CompositeView? or is there any other alternative to include all compositeViews into a single item, like:

Collection(CompositeView???)
  -> CompositeView-category1
      -> itemView-product1-1
      -> itemView-product1-2
  -> CompositeView-category2
      -> itemView-product2-1
      -> itemView-product2-2
Foi útil?

Solução

I would suggest you to use a Layout view, inside this layout you can have a region for each category and draw your composite views on these regions.

the benefit of the Layout view in marionette is that you can pass a template that should contain all the HTML that you need initially, for example a header with buttons to add and remove categories etc.

CategoriesLayout = Backbone.Marionette.Layout.extend({
   template: "#layout-template",

   regions: {
    category1Region: "#category1",
    category2Region: "#category2"
  }
});;

and then you can render your composite views inside the regions

categoriesLayout = new CategoriesLayout();
categoriesLayout.category1Region.show(new CategoryView());

this way you can show/close your views using the Region functionality. If you need to add the regions on the fly that is also possible if you render the HTML with Marionette.renderer and then attach your regions to the Layout.

additionally you may want to take a look at the region manager of Marionette that helps you to manage a set of regions.

EDIT

I did a jsfiddle to demonstrate this, this is just an example but I think the idea is there...

http://jsfiddle.net/VS9hA/28/

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

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

 var layout = new MyLayout({el:"#container"});
 layout.render();
 var dynamicRegion = sampleModel.get('categoryName');
 layout.addRegion(dynamicRegion,"#dynamic"); // adding the region on the fly
 layout[dynamicRegion].show(sampleView); // using it!

so the answer to your question in the comment

  categoriesLayout[dynamicRegion].show(new CategoryView())

just make sure the DOM element is there (#dynamic) if its not, just append the HTML on your layout view or use the marionette.Renderer Object to pass a nice template for your region.

And there is no problem adding a region on the fly, marionette has a method for that scenario.

Hope that helps,

Outras dicas

I would advise against using Layouts for your top level view because then you have to manually create a region for each new category you add. Using a CollectionView or CompositeView on the other hand allows for an unlimited number of categories (and even an emptyView when there are none) without extra work.

The decision of whether to use a CompositeView or CollectionView as the top view will depend on whether or not you need a template wrapper for it (for buttons, etc). If you don't then just go with a CollectionView.

I think you're on the right track with each category being a CompositeView so you can have the template with tbody as the 'itemViewContainer':

<table>
   <tbody>
   </tbody>
</table>

in the category view:

itemViewContainer: 'tbody'

And then the products (ItemViews) will use:

tagName: 'tr'
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top