How to show CompositeView with multiple children view in Backbone Marionette

£可爱£侵袭症+ 提交于 2019-12-05 00:29:15

问题


The Starting Problem

I have a CompositeView (a table) for which each model in the collection is represented as two table rows, with a template like:

<tr class="row-parent">
    <td>parent info here</td>
</tr>
<tr class="row-child">
    <td>child info here</td>
</tr>

With an ItemView like this:

var ItemView = Backbone.Marionette.ItemView.extend({
    template: ItemTmpl
});

Even though they are named 'parent' and 'child', they are actually peer members of the same model. If I don't specify a tagName, Backbone will wrap each view in a <div> which is both invalid HTML and also breaks the layout.

The First Attempt at a Solution

So I figured, why not remove the outer <tr> tags and let Backbone add them in. So I updated my template to be like:

    <td>parent info here</td>
</tr>
<tr class="row-child">
    <td>child info here</td>

And updated the view to:

var ItemView = Backbone.Marionette.ItemView.extend({
    template: ItemTmpl,
    tagName: 'tr',
    className: 'row-parent'
});

I was hoping that an outer tag would combine with the inner tag fragments, but Marionette didn't like that. It only showed the row-child. So I'm not sure where to go from here. I'm considering two strategies but haven't gone into much details yet.

Moving Forward: Plan A

Override whatever part of Backbone creates the extra div to not create it, or override the part of Marionette which appends the view to remove the div just before appending.

Moving Forward: Plan B

Create a new type of view called CompositeMultiView which, naturally, would extend off CompositeView and allow you two specify a second ItemView, or maybe just an array of views, all of which would be rendered for each model given. This plan seems like a lot more work but less hacked.


Does anyone have any better suggestions, workarounds or concrete pointers as to how I would go about implementing either of the two above plans?

Here is a mockup of what the table should look like:


回答1:


I struggled with that same problem until I finally discovered today, that a table can have multiple tbody tags, each one containing multiple tr tags.

This is actually the answer provided to a similar backbone question.

So your ItemView would become:

var ItemView = Backbone.Marionette.ItemView.extend({
    template: ItemTmpl,
    tagName: 'tbody'
});

And the generated html:

<table>
  <!-- first item -->
  <tbody>
    <tr class="row-parent">
      <td>parent info here</td>
    </tr>
    <tr class="row-child">
      <td>child info here</td>
    </tr>
  </tbody>
  <!-- second item -->
  <tbody>
    <tr class="row-parent">
      <td>parent info here</td>
    </tr>
    <tr class="row-child">
      <td>child info here</td>
    </tr>
  </tbody>
  ...
</table>



回答2:


You could try modifying the CompositeView as follows:

  1. Specify itemView as an array of views
  2. Override addChildView to render each view for each model

This solution ends up looking a lot like your "Plan B". Give it a shot:

itemView: [My.ParentView, My.ChildView],

addChildView: function(item, collection, options){
  this.closeEmptyView();
  var itemViews = this.getItemView(item);
  var index = this.collection.indexOf(item);

  _.each(itemViews, function(ItemView) {
    this.addItemView(item, ItemView, index);
  });
}

I haven't thought through whether this would handle model events such as destroy, but I believe it should handle them gracefully.




回答3:


Dirty solution: Add a custom render function to your ItemView

// Or whatever template you use
var template = Handlebars.compile(datepickerTemplate);

var ItemView = Backbone.Marionette.ItemView.extend({
    render: function(){
        var html = template(this.model.toJSON());
        var newElement = $(html);
        this.$el.replaceWith(newElement);
        this.setElement(newElement);
        return this;
    }
});

This should remove the extra div wrapping



来源:https://stackoverflow.com/questions/18689150/how-to-show-compositeview-with-multiple-children-view-in-backbone-marionette

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!