所以这是我的情景:
我有一个充满模型的Backbone Collection。然而,出于性能原因,这些并非全部"楷模。我的#34;完整"模型非常大(想象每个"完全"模型有一个同样大的对象的子集合),所以当我从服务器获取Collection时,我返回一个" partial"其属性是" full"的子集的模型model(例如,我只返回子集合的长度而不是完整的子集合),足以在列表视图中向用户显示模型。
现在,当用户从列表中选择一个项目时,我会获取" full"从服务器建模并显示该模型的详细信息视图。我遇到的问题是现在我有两个相同型号的版本,一个"部分"在收集和一个"完整",手动必须保持同步不是正确的做事方式。
我想知道的是,是否存在一种现有模式(在Backbone或Marionette中)用于"填充" a"部分"模型化为"完整"模型同时保留所有相同的参考文献,并用于"减少"相同的模型来自" full"模型化为" partial"当我们不再需要所有额外数据时(即用户导航到列表中的另一个项目)进行建模。
我可以完全控制应用程序的前端和后端,如果模式需要我更改服务器返回的内容,我可以相应地进行更改。
答案 0 :(得分:1)
您正在表示单个域对象(尽管有两种不同的形式),因此您应该使用单个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')
}
})
此模式优先使用自定义inflate
和deflate
事件来触发change
,因为它在语义上更准确。
当然,您可以通过维护应该在/缩小的属性名称数组来干掉代码。
答案 1 :(得分:0)
就像您的收藏集中包含“部分”模型的网址一样,您的模型应该包含完整版本的网址:
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({});
您不会有同一型号的两个版本。集合视图中的模型现在将具有所有属性,但它只显示模板中的内容。
就“人口减少”而言似乎没有必要。如果再次单击该项目,您甚至可以检查“完整”模型数据是否可用并丢失额外的提取。如果您确实要删除数据,请继续在模型上创建一个方法来取消设置属性。