我有两个函数可以在 Backbone.js 模型上调用fetch。第一个函数使用id创建一个新的模型示例并调用fetch(),第二个函数使用id从集合中检索一个现有的模型示例并调用fetch()。在第一个函数中,模型的parse函数被触发,但在第二个函数上没有...我不知道为什么。
第一个(触发器分析)
App.fetchItemById = function (id) {
App.myItem = new App.Item({id: id});
App.myItem.fetch({
traditional: true,
data: {
elements: 'all',
format:'json',
},
success: function(){
App.myItemView = new App.ItemView({
el: $('#active-item'),
model: App.myItem,
});
App.myItemView.render();
}
});
};
第二个(不触发解析)
App.fetchItemFromCollectionById = function (id) {
App.myItem = App.myItemCollection.get(id);
App.myItem.fetch({
traditional: true,
data: {
elements: 'all',
format:'json',
},
success: function(){
App.myItemView = new App.ItemView({
el: $('#active-item'),
model: App.myItem,
});
App.myItemView.render();
}
});
};
我读过的所有文档都说模型的解析函数总是在获取时调用的。
有人知道为什么解析在第二个上没有被触发吗?
以下是模型定义:
App.Item = Backbone.Model.extend({
urlRoot: '/api/v1/item/',
defaults: {
},
initialize: function(){
},
parse : function(response){
console.log('parsing');
if (response.stat) {
if (response.content.subitems) {
this.set(‘subitems’, new App.SubitemList(response.content.subitems, {parse:true}));
delete response.content.subitems;
this
}
return response.content;
} else {
return response;
}
},
});
已修复,感谢EMILE和COREY -解决方案如下
结果是,当我第一次加载App.MyItemCollection时,集合中的模型只是泛型模型,没有正确地转换为App. Item的示例。App.Item”到集合定义中解决了这个问题.见下图:
原件
App.ItemList = Backbone.Collection.extend({
url: '/api/v1/item/',
parse : function(response){
if (response.stat) {
return _.map(response.content, function(model, id) {
model.id = id;
return model;
});
}
}
});
已更新、已解决问题
App.ItemList = Backbone.Collection.extend({
url: '/api/v1/item/',
model: App.Item,
parse : function(response){
if (response.stat) {
return _.map(response.content, function(model, id) {
model.id = id;
return model;
});
}
}
});
2条答案
按热度按时间mo49yndu1#
parse
仅在fetch
成功时调用在 Backbone.js 源代码中,我们可以看到
parse
函数仅在fetch
异步请求成功时被调用。parse
上的文档说明:每当服务器返回模型的数据时,在
fetch
和save
中调用parse。假设
fetch
失败,服务器不会返回模型数据,因此不会调用parse。为了使
fetch
成功地应用于现有模型,默认行为要求模型在其attributes
哈希中具有id
。cid
仅用于在本地区分模型,不能单独用于提取。模型的一个特殊属性,cid或client id是一个唯一的标识符,在所有模型首次创建时自动分配给它们。当模型还没有保存到服务器,还没有最终的真实id,但已经需要在UI中可见时,Client id是很方便的。
确保集合使用我们自己的模型
正如Cory Danielson所提到的,如果
myItemCollection
集合上没有设置model
属性,则将调用默认模型parse
,而不是您的App.Item
模型的parse
。模型不应在
parse
函数中示例化,因为这是集合的职责。如果我们不对集合设置
model
属性,那么无论何时我们在集合上使用add
或set
,我们都将面临同样的问题,即我们的新模型将是Backbone.Model
示例,而不是App.Item
示例。避免
parse
中的副作用您的
parse
函数有一些您应该了解的代码味道:*
parse
不应该对模型有任何副作用。它应该接收数据并返回转换后的数据,仅此而已。undefined
。delete
是低效的**,最好只返回一个新对象。无论如何,这是另一个你应该避免的副作用。小心嵌套模型和集合
话虽如此,我发现您在解析中将一个集合嵌套在模型的
attributes
散列中。我建议您不要使用这种模式,原因如下:*模型变得非常脆弱,您需要非常小心,始终调用
parse: true
,并且永远不要在模型之外设置subitems
。default
现在变得更加复杂**,因为您必须记住属性中有一个集合。*由于同样的原因,保存模型更加复杂。
*子项中的更改不会触发父模型中的事件。
有多种解决方案,这些我已经在这里回答:
wmvff8tz2#
有可能你的集合没有使用相同的模型类作为它的模型属性,这就是为什么在那个特定的模型上解析不会被调用的原因。
如果
model
属性没有设置为您期望的模型,它将不会对该模型调用parse。默认情况下,集合将使用Backbone.Model。你可能会有这样的东西