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')
}
})
此模式优先使用自定义 inflate
和 deflate
事件而不是触发 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" 模型数据是否可用并丢失额外的提取。如果你真的想删除数据,那么继续在模型上创建一个方法来取消设置属性。
这是我的场景:
我有一个 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')
}
})
此模式优先使用自定义 inflate
和 deflate
事件而不是触发 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" 模型数据是否可用并丢失额外的提取。如果你真的想删除数据,那么继续在模型上创建一个方法来取消设置属性。