gpt4 book ai didi

javascript - 主干模型获取()不调用解析

转载 作者:行者123 更新时间:2023-11-30 14:56:22 25 4
gpt4 key购买 nike

我有两个函数在 Backbone 模型上调用 fetch。第一个使用 id 创建模型的新实例并调用 fetch(),第二个使用 id 从集合中检索现有模型实例并调用 fetch()。在第一个中,模型的解析函数被触发,但在第二个中没有……我不知道为什么。

第一个(触发解析)

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;
});
}
}
});

最佳答案

parse 仅在成功 fetch

时调用

Backbone source ,我们可以看到只有在fetch异步请求成功时才会调用parse函数。

fetch: function(options) {
options = _.extend({parse: true}, options);
var model = this;
var success = options.success;

// The success callback is replaced with this one.
options.success = function(resp) {
// parse is called only if the fetch succeeded
var serverAttrs = options.parse ? model.parse(resp, options) : resp;
// ...snip...
// then the provided callback, if any, is called
if (success) success.call(options.context, model, resp, options);

};
wrapError(this, options);
return this.sync('read', this, options);
},

documentation on parse说:

parse is called whenever a model's data is returned by the server, in fetch, and save.

假设fetch失败,服务器没有返回模型数据,所以不会调用parse。

要使 fetch 成功处理现有模型,默认行为要求模型在其 attributes 哈希中具有 id

cid仅用于在本地区分模型,不会单独用于提取。

A special property of models, the cid or client id is a unique identifier automatically assigned to all models when they're first created. Client ids are handy when the model has not yet been saved to the server, and does not yet have its eventual true id, but already needs to be visible in the UI.


确保集合使用我们自己的模型

作为mentioned by Cory Danielson , 如果 model property未在 myItemCollection 集合上设置,将调用默认模型 parse,而不是您的 App.Item 模型的 parse.

不应在 parse 函数中实例化模型,因为它是集合的职责。

App.ItemList = Backbone.Collection.extend({
model: App.Item, // make sure to set this property
url: '/api/v1/item/',
parse : function(response){
if (response.stat) {
return _.map(response.content, function(model, id) {
model.id = id;
return model;
});
}
}
});

如果我们不设置 model property在集合上,任何时候我们在集合上使用 addset 时,我们都会面临同样的问题,我们的新模型将是 Backbone.Model 实例而不是 App.Item 实例。


避免parse中的副作用

你的 parse 函数有一些你应该知道的代码味道:

  • parse 不应对模型产生任何副作用。它应该接收数据并返回转换后的数据,仅此而已。
  • 它应该总是返回数据。在您的情况下,它仅在特定条件下返回数据,否则返回 undefined
  • 使用delete 效率低下,最好只返回一个新对象。无论如何,这是您应该避免的另一个副作用。

小心嵌套模型和集合

话虽如此,我看到您在解析中将集合嵌套在模型的 attributes 散列中。出于以下几个原因,我建议不要使用这种模式:

  • 模型变得非常脆弱,您需要非常小心地始终调用 parse: true,并且永远不要在模型之外设置 subitems模型。
  • 它会在创建模型后立即为子项创建所有模型,这对于大量模型而言效率低下。 延迟初始化子项会有所帮助。
  • 使用default 现在更加复杂,因为您必须记住属性中有一个集合。
  • 出于同样的原因,保存模型更加复杂
  • 子项内的更改不会触发父模型中的事件

我已经在这里回答了这些问题的多种解决方案:

关于javascript - 主干模型获取()不调用解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47212079/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com