PhD*_*PhD 81 ajax jquery backbone.js
我很清楚它可以完成,我已经看了很多地方(包括:保存整个集合的最佳实践?).但是我仍然不清楚它是用代码写的"究竟是怎么样的"?(这篇文章用英文解释.有一个特定于javascript的解释很棒:)
假设我有一组模型 - 模型本身可能有嵌套集合.我已经覆盖了父集合的toJSON()方法,我得到了一个有效的JSON对象.我希望"保存"整个集合(相应的JSON),但是主干似乎没有内置该功能.
var MyCollection = Backbone.Collection.extend({
model:MyModel,
//something to save?
save: function() {
//what to write here?
}
});
Run Code Online (Sandbox Code Playgroud)
我知道你要说的某个地方:
Backbone.sync = function(method, model, options){
/*
* What goes in here?? If at all anything needs to be done?
* Where to declare this in the program? And how is it called?
*/
}
Run Code Online (Sandbox Code Playgroud)
一旦"查看"完成处理,它就负责告诉集合在服务器上"保存"自己(能够处理批量更新/创建请求).
出现的问题:
如果它确实是一个棘手的工作,那么我们可以在视图中调用jQuery.ajax并传递this.successMethod
或this.errorMethod
作为成功/错误回调?? 它会起作用吗?
我需要与骨干的思维方式保持同步 - 我知道我肯定错过了一些东西,同步整个系列.
bra*_*ing 64
我当前的想法是不要覆盖Backbone.Collection上的save方法上的方法,而是将该集合包装在另一个Backbone.Model中并覆盖其上的toJSON方法.然后Backbone.js会将模型视为单一资源,而您不必破解backone认为过多的方式.
请注意,Backbone.Collection具有toJSON方法,因此您的大部分工作都是为您完成的.您只需将包装器Backbone.Model的toJSON方法代理到Backbone.collection.
var MyCollectionWrapper = Backbone.Model.extend({
url: "/bulkupload",
//something to save?
toJSON: function() {
return this.model.toJSON(); // where model is the collection class YOU defined above
}
});
Run Code Online (Sandbox Code Playgroud)
hac*_*ack 25
一个非常简单的......
Backbone.Collection.prototype.save = function (options) {
Backbone.sync("create", this, options);
};
Run Code Online (Sandbox Code Playgroud)
...将为您的馆藏提供一种保存方法.请记住,无论发生什么变化,都会将所有集合的模型发布到服务器.选项只是普通的jQuery ajax选项.
我最终只是采用了"保存"方法,并在其中调用了$ .ajax.它给了我更多的控制权,而不需要添加一个包装类,如@brandgonesurfing建议的那样(虽然我非常喜欢这个主意:)正如我所说的那样,因为我已经重写了collection.toJSON()方法,所以我所做的就是使用它在ajax电话中......
希望这可以帮助那些偶然发现它的人......
这实际上取决于客户端和服务器之间的合同.这是一个简化的CoffeeScript示例,其中PUT to /parent/:parent_id/children
with {"children":[{child1},{child2}]}
将用PUT中的内容替换父项的子项并返回{"children":[{child1},{child2}]}
:
class ChildElementCollection extends Backbone.Collection
model: Backbone.Model
initialize: ->
@bind 'add', (model) -> model.set('parent_id', @parent.id)
url: -> "#{@parent.url()}/children" # let's say that @parent.url() == '/parent/1'
save: ->
response = Backbone.sync('update', @, url: @url(), contentType: 'application/json', data: JSON.stringify(children: @toJSON()))
response.done (models) => @reset models.children
return response
Run Code Online (Sandbox Code Playgroud)
这是一个非常简单的例子,你可以做更多......这实际上取决于执行save()时数据的状态,发送到服务器所需的状态以及服务器给出的内容背部.
如果您的服务器没有PUT [{child1},{child2]
,那么您的Backbone.sync线可以更改为response = Backbone.sync('update', @toJSON(), url: @url(), contentType: 'application/json')
.
答案取决于您要对服务器端的集合执行什么操作.
如果您必须使用帖子发送其他数据,则可能需要包装器模型或关系模型.
使用包装器模型,您始终必须编写自己的解析方法:
var Occupants = Backbone.Collection.extend({
model: Person
});
var House = Backbone.Model.extend({
url: function (){
return "/house/"+this.id;
},
parse: function(response){
response.occupants = new Occupants(response.occupants)
return response;
}
});
Run Code Online (Sandbox Code Playgroud)
我认为关系模型更好,因为您可以更容易地配置它们,并且您可以使用 includeInJSON选项进行调节,该属性将放入您发送到休息服务的json中.
var House = Backbone.RelationalModel.extend({
url: function (){
return "/house/"+this.id;
},
relations: [
{
type: Backbone.HasMany,
key: 'occupants',
relatedModel: Person,
includeInJSON: ["id"],
reverseRelation: {
key: 'livesIn'
}
}
]
});
Run Code Online (Sandbox Code Playgroud)
如果您不发送其他数据,则可以同步集合本身.在这种情况下,您必须为集合(或集合原型)添加一个save方法:
var Occupants = Backbone.Collection.extend({
url: "/concrete-house/occupants",
model: Person,
save: function (options) {
this.sync("update", this, options);
}
});
Run Code Online (Sandbox Code Playgroud)