Marionette.js CompositeView - 如何在不嵌套的情况下渲染模型和集合

时间:2014-11-18 17:00:03

标签: javascript backbone.js marionette nested-views

我想请求一些帮助,因为我一直试图解决这个问题。我在树结构和CompositeViews上阅读了Derick Bailey's blog post。我也读过David Sulc's,但我认为我的用例与那里描述的用例略有不同。注意:我的项目使用Marionette.js 1.0.3。

我正在尝试构建一些可以像收件箱一样工作的内容,并在表格中显示电子邮件。电子邮件可能是一个线程,这意味着它将包含与其链接的其他电子邮件。收件箱视图以<table>呈现,其中每个<tr>都是电子邮件。我的JSON看起来像:

[
  {id: 1, subject: 'One', threads: []},
  {id: 2, subject: 'Two', threads: [
    {id: 3, subject: 'Three', threads: []},
    {id: 4, subject: 'Four', threads: []}
  ]},
  {id: 5, subject: 'Five', threads: []}
]

我的观点配置如下:

InboxView = Marionette.CompositeView.extend({
  // edited for brevity
  initialize: function(options) {
    this.itemView = EmailView;
  }
  // edited for brevity
});

EmailView = Marionette.CompositeView.extend({
  // edited for brevity
  tagName: 'tr',
  initialize: function(options) {
    this.collection = this.model.get('threads');
  },
  onRender: function() {
    if (this.model.isThread()) this.$el.addClass('thread');
  }
  // edited for brevity
});

我遇到的问题是,如果我通过渲染模型一次然后将线程集合渲染一次来让CompositeView为我工作,我最终得到两个表行<tr>(每个线程一个) )在原始电子邮件(父母)的<tr>内。

我正在尝试重用InboxViewEmailView中的功能。我最终想要的是一个表,所有行都显示在同一级别。

如果您正在阅读此内容并想要帮助我,请提前感谢您!

1 个答案:

答案 0 :(得分:0)

首先,您应该将视图附加到DOM。发生错误,因为子视图在附加到DOM之前呈现。您可以覆盖一些方法来解决问题。这样就可以了:

EmailView = Marionette.CompositeView.extend({   

    className: function () {
        return this.model.isThread() ? 'thread' : null;
    },

    initialize: function (options) {
        this.collection = new Backbone.Collection(this.model.get('threads'));
    },

    renderItemView: function(view, index) {        
        this.$el.parent().append(view.el);

        view.render();
    }

});

InboxView = Marionette.CompositeView.extend({

    itemView: EmailView,

    ui: {
        $tbody: 'tbody'  
    },

    renderItemView: function (view, index) {
        this.ui.$tbody.append(view.el);

        view.render();
    }

});

JSFiddle http://jsfiddle.net/d1krtxtr/