Backbone 在 Collection 中填充模型

Backbone populate Model inside of a Collection

这是我的场景:

我有一个 Backbone Collection 全是模型。但是,出于性能原因,这些不是 "full" 模型。我的 "full" 模型非常大(假设每个 "full" 模型都有一个同样大的 objects 的 sub-collection),所以当我从服务器获取 Collection 时,我return 一个 "partial" 模型的数组,其属性是 "full" 模型的子集(例如我 return 只有 sub-collection 的长度而不是完整的sub-collection),刚好足以在列表视图中向用户显示模型。

现在,当用户从列表中选择一项时,我会从服务器获取 "full" 模型并显示该模型的详细信息视图。我遇到的问题是,现在我有同一模型的两个版本,一个 Collection 中的一个 "partial" 和一个 "full" 中的一个 "full",并且必须手动使它们保持同步是不正确的做事的方式。

我想知道是否存在将 "populating" "partial" 模型转换为 [=22= 的现有模式(在 Backbone 或 Marionette 中) ] 模型,同时保留所有相同的引用,并且当我们不再需要所有额外数据(即用户导航到列表中的另一个项目)。

我可以完全控制我的应用程序的 front-end 和 back-end,如果模式需要我更改服务器 return 的内容,我可以相应地进行更改。

您代表的是一个域对象(虽然有两种不同的形式),因此您应该使用一个 Model 实例来涵盖这两种情况。

一个相当干净的模式:

var MyModel = Backbone.Model.extend({
  // ... existing code...

  inflate: function() {
    return $.ajax({
      // parameters to fetch the full version
    }).then(function(data) {
      // process the response - something like this:
      this.set({
        a: data.a,
        b: data.b
      }, { silent: true })

      this.trigger('inflate')
    })
  },

  deflate: function() {
    this.unset('a', { silent: true });
    this.unset('b', { silent: true });

    // any other cleanup to prevent leaking the large attributes

    this.trigger('deflate')
  }
})

此模式优先使用自定义 inflatedeflate 事件而不是触发 change,因为它在语义上更准确。

当然,您可以通过维护一组应该是 in/deflated.

的属性名称来 DRY 代码

就像您的 collection 对 "partial" 模型有 URL 一样,您的模型应该对完整版本有 URL:

var Library = Backbone.Collection.extend({
    model: Book,
    url: "/books"
});

var Book = Backbone.Model.extend({
    url: function () {
        return "/books/" + this.get("id");
    }
});

当您单击项目视图时使用相同的模型,调用 fetch(),并将其传递到详细视图。

var BookView = Backbone.View.extend({

    tagName: "li",

    events: {
        "click .details": "openBook"
    },

    initialize: function() {
        // ...
    },

    openBook: function () {
        this.model.fetch();
        var bookDetailView = new BookDetailView({ model: this.model });
        // Or create the view after successful fetch...
    }

    // ...

});

var BookDetailView = Backbone.View.extend({});

同一模型不会有两个版本。 collection 视图中的模型现在将具有所有属性,但它只会显示模板中的内容。

就"depopulating"而言,似乎没有必要。如果再次单击该项目,您甚至可以检查 "full" 模型数据是否可用并丢失额外的提取。如果你真的想删除数据,那么继续在模型上创建一个方法来取消设置属性。