Javascript 从第三方API填充模型
我正在为一个个人项目使用主干网,在这个项目中,我创建了一个名为Javascript 从第三方API填充模型,javascript,backbone.js,backbone-views,backbone.js-collections,Javascript,Backbone.js,Backbone Views,Backbone.js Collections,我正在为一个个人项目使用主干网,在这个项目中,我创建了一个名为MyModel的模型。在初始化此模型时,我想从第三方API的JSON响应中填充其属性: app.MyModel = Backbone.Model.extend({ url: 'https://api.xxxxxx.com/v12_1/item?id=53444d0d7ba4ca15456f5690&appId=xxxx&appKey=yyyy', defaults: { n
MyModel
的模型。在初始化此模型时,我想从第三方API的JSON响应中填充其属性:
app.MyModel = Backbone.Model.extend({
url: 'https://api.xxxxxx.com/v12_1/item?id=53444d0d7ba4ca15456f5690&appId=xxxx&appKey=yyyy',
defaults: {
name: 'Default Name'
}
});
此模型用于将在另一个模型中嵌入的属性中使用的集合:
app.MyModels = Backbone.Collection.extend({
model: app.MyModel
});
app.MyModel2 = Backbone.Model.extend({
// Default attributes
defaults: {
name: 'Default Name'
},
initialize: function() {
this.myModels = new app.MyModels();
this.myModels.on('change', this.save);
}
});
在为MyModel2
创建的视图中,我向全局元素添加了一个侦听器,这样我们就可以初始化MyModel
并将MyModels
的实例添加到MyModel2
内部
app.MyModel2View = Backbone.View.extend({
initialize: function() {
// ...some code...
var self = this;
this.$(".add-myModel").click(function() {
var myModel = new app.MyModel();
myModel.fetch();
self.model.myModels.add(myModel);
});
// ...some code...
},
// ...some code...
});
这实际上实现了预期目标,但在单击元素并添加实例时,控制台中会抛出一个错误:
backbone.js:646 Uncaught TypeError: this.isNew is not a function
在主干网中,这是从外部API填充模型实例的正确方法吗?我正在试图找出此错误的原因。如果没有更完整的信息,很难说,但在保存
MyModels
时,您似乎没有正确设置上下文:
this.myModels.on('change', this.save);
这是on()
方法的最后一个可选参数,因此可能:
this.myModels.on('change', this.save, this);
请参阅中的详细信息,而他只关注最可能出现的错误,而让您处理所有其他问题。我将在我的回答中对此进行详细阐述
查询字符串中ID为的模型URL API的URL非常复杂,每次需要时复制粘贴都很麻烦。最好在一个地方处理URL,实现这一点的一种方法是使用简单的服务 用API信息填充它 然后,可以创建基础模型和集合(或替换默认主干行为) 那么使用它就这么简单:
app.MyModel = app.BaseModel.extend({
urlRoot: app.API.url('item'),
})
app.Collection = app.BaseCollection.extend({
model: app.MyModel,
url: app.API.url('collection-items'),
});
以下测试输出:
var-app=app | |{};
(功能(){
app.API={
协议:“https”,
域:“api.xxxxxx.com”,
根目录:'/v12_1/',
参数:{
appId:'xxxx',
appKey:'yyy',
},
/**
*获取完整的API url以及可选路径。
*@param{String}路径(可选)以添加到url。
*@return{String}包含协议、域、根的完整API url。
*/
url:函数(路径){
路径=路径| |“”;
如果(path.slice(-1)!='/')路径+='/';
返回this.protocol+“:/”+this.domain+this.root+路径;
},
/**
*将查询字符串添加到url,并与默认API参数合并。
*查询字符串前的@param{String}url(可选)
*@param{Object}params转换为查询字符串
*@return{String}例如:“你的url?param=value&otherparam=123”
*/
applyParams:函数(url、参数){
返回(url | |“”)+“?”+$.param({}.extend({},this.params,params));
},
};
app.BaseModel=Backbone.Model.extend({
setId:函数(id,选项){
返回this.set(this.idAttribute,id,options);
},
url:function(){
var基=
_.result(此“urlRoot”)||
_.result(此.collection为“url”)||
urlError();
var id=this.get(this.idAttribute);
返回app.API.applyParams(base,this.isNew(){
id:encodeURIComponent(id)
});
},
});
app.BaseCollection=Backbone.Collection.extend({
型号:app.BaseModel,
同步:函数(方法、集合、选项){
var url=options.url | | | | |结果(模型,'url')| | urlError();
options.url=aop.API.applyParams(url);
返回app.BaseCollection.super.sync.apply(这是参数);
}
});
app.MyModel=app.BaseModel.extend({
urlRoot:app.API.url('item'),
})
app.Collection=app.BaseCollection.extend({
型号:app.MyModel,
url:app.API.url('collection-items'),
});
var model=new app.MyModel();
log(“新模型url:,model.url());
型号setId(“53444d0d7ba4ca15456f5690”);
log(“现有模型url:,model.url());
var collection=新建app.collection();
log(“集合url:,”结果(集合,'url');
var modelUrlThroughCollection=新建app.BaseModel({
id:“test1234”
});
collection.add(modelUrlThroughCollection);
log(“通过集合建模:”,modelUrlThroughCollection.url());
})();代码>
虽然我尽了最大努力,但如果您添加一个API响应示例和其他可用端点,这将非常有帮助。此外,您应该真正地使用有意义的名称,即使它只是一个示例,例如MyModel
、MyModels
、MyModel2
和MyModel2View
都不是描述性名称。
app.BaseModel = Backbone.Model.extend({
setId: function(id, options) {
return this.set(this.idAttribute, id, options);
},
url: function() {
var base =
_.result(this, 'urlRoot') ||
_.result(this.collection, 'url') ||
urlError();
var id = this.get(this.idAttribute);
return app.API.applyParams(base, this.isNew() || { id: encodeURIComponent(id) });
},
});
app.BaseCollection = Backbone.Collection.extend({
model: app.BaseModel,
sync: function(method, collection, options) {
var url = options.url || _.result(model, 'url') || urlError();
options.url = aop.API.applyParams(url);
return app.BaseCollection.__super__.sync.apply(this, arguments);
}
});
app.MyModel = app.BaseModel.extend({
urlRoot: app.API.url('item'),
})
app.Collection = app.BaseCollection.extend({
model: app.MyModel,
url: app.API.url('collection-items'),
});