0

我想寻求一些帮助,因为我已经尝试解决这个问题一段时间了。我已经阅读了Derick Bailey关于树结构和 CompositeViews的博客文章。我也阅读了David Sulc 的文章,但我认为与那里描述的用例略有不同。注意:我的项目使用 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>父母)。

InboxView中存在EmailView我正在尝试重用的功能。我试图最终得到的是一个所有行都显示在同一级别的表。

如果您正在阅读本文并想帮助我,请提前感谢您!

4

1 回答 1

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/

于 2014-11-18T18:57:29.167 回答