我正在设置骨干同步机制,并且有点困惑在哪里为模型生成id。
当我创建一个新模型时,骨干应该生成并设置id,还是我应该实现一个id生成方法,或者是否存在某种机制,我将数据“输出”到服务器,生成id并返回一个带有id?
的模型答案 0 :(得分:56)
我提供了第二个答案来简化您需要学习的代码,以获得您正在思考的要点 - 从模型到服务器的实际回合以及ID如何发挥作用。
说你定义一个模型 - 让我们去侏罗纪公园。
// Define your model
var Dinosaur = Backbone.Model.extend({
defaults: {
cavemanEater: undefined // Has one property, nom nom or not.
},
urlRoot: 'dino' // This urlRoot is where model can be saved or retrieved
});
var tRex = new Dinosaur({'cavemanEater':true});
你现在已经实例化了一个肉食者的恐龙。轰鸣声。
console.log(tRex);
您应该注意的是,在tRex的属性中,您的模型没有id。相反,您将看到一个cID,您可以将其视为Backbone自动分配给您的模型的临时ID。当模型没有id时,它被认为是新的。持久化模型(数据库或本地存储)的概念允许您在创建它之后返回该资源并执行诸如保存(PUT)或销毁(DELETE)之类的操作。如果您无法直接指向它,那么很难找到该资源!为了找到该资源,您的模型需要一个id,这是目前没有的。
因此,正如上面的答案所解释的那样,为您的Backbone提供资源ID是您的数据库(或localstorage或其他解决方案)的工作。大多数情况下,这来自资源ID本身,也就是 - 某些表中模型的主键ID。
使用我的设置,我使用PHP和mySQL。我会有一个名为恐龙的表,每一行都是我的恐龙模型的持久表示。所以我有一个id列(唯一的自动递增int)和cavemanEater(bool)。
数据通信流程就是这样发生的。
以下是带注释的代码。
客户端:
tRex.save();
// {'cavemanEater':true} is sent to my server
// It uses the urlRoot 'dino' as the URL to send. e.g. http://www.example.com/dino
SERVER:
// Is setup to accept POST requests on this specific ROUTE '/dino'
// Server parses the json into something it can work with, e.g. an associative array
// Server saves the data to the database. Our data has a new primary id of 1.
// Data is now persisted, and we use this state to get the new id of this dino.
$dinoArray = array('id'=>1, 'cavemanEater'=>true);
$dinoJSON = json_encode($dinoArray);
// Server does something to send $dinoJSON back.
客户端:
// If successful, receives this json with id and updates your model.
现在你的tRex有一个id = 1.或者我应该说......
tRex.toJSON();
// RETURNS {'id':'1', 'cavemanEater':'true'}
祝贺。如果你这样做tRex.isNew()
,它将返回false。
Backbone非常聪明。它知道POST已经拥有资源ID的新模型和PUT模型。
下次执行此操作时:
tRex.save();
Backbone会向以下网址发出PUT请求。
顺便说一下,这是默认行为。但你会注意到的是,URL与保存不同。在服务器上,您需要一个接受/ dino /:id而不是/ dino
的路由默认情况下,它会为你的模型使用/ urlRoot /:id路由模式,除非你另外调整它。
不幸的是,恐龙灭绝了。
tRex.destroy();
这会打电话......你能猜到吗?是的。删除/ dino / 1的请求。
您的服务器必须区分对不同路由的不同请求才能使Backbone工作。有几种服务器端技术可以做到这一点。
如果您使用Ruby,有人会提到Sinatra。就像我说的,我使用PHP而且我使用SLIM PHP Framework。它的灵感来自Sinatra所以它很相似,我喜欢它。作者写了一些干净的代码。这些RESTful服务器实现的工作方式不在本讨论的范围之内。
我认为这是新的Backbone数据的基本全部旅行,没有id,跨越互联网到你生成的服务器,并发回资源ID,让你的模型永远幸福地生活。 (或destroy()
不......)
我不知道这对你来说是否太初学,但希望它会帮助遇到这个问题的其他人。使用Backbone非常有趣。
其他类似的答案: Ways to save Backbone JS model data
答案 1 :(得分:9)
或者是否存在某种机制,其中我&#34; PUT&#34;数据到服务器,生成id并返回id为<?p>的模型
有点儿。当您调用模型的save方法时,backbone会生成POST XHR,而您的应用程序服务器应该使用包含id的JSON进行响应。 您可以在此处查看示例:http://addyosmani.com/blog/building-backbone-js-apps-with-ruby-sinatra-mongodb-and-haml/
从链接引用:
post '/api/:thing' do
# parse the post body of the content being posted, convert to a string, insert into
# the collection #thing and return the ObjectId as a string for reference
oid = DB.collection(params[:thing]).insert(JSON.parse(request.body.read.tos))
"{\"id\": \"#{oid.to_s}\"}"
end
如果您不了解Ruby,请记住该方法会自动返回所评估的最后一个表达式。
答案 2 :(得分:4)
我从您的问题中了解到,您希望拥有一个包含服务器上存在的模型的集合。为了将这些模型放入集合中,您必须在集合上添加调用'fetch()'。
url将是“/ users”或类似的东西,它必须返回包含用户数据的对象数组。然后,数组中的每个项都将传递给UserCollection.add()。好吧,实际上它会一下子全部通过,但你明白了。
在此之后填充您的收藏。模型上的URL用于更新和保存单个模型。该集合的url也将用于创建模型。 Backbone的同步是RESTful,就像Ruby on Rails一样。您可以在Ruby on Rails的文档中了解更多相关信息:
http://guides.rubyonrails.org/routing.html
您通常会为您的模型提供与控制器不同的网址。填充你的收藏后,你有每个模型的id,因为它们来自服务器。
现在,当您根据用户输入添加新模型时,您可以执行以下操作:
var HomeModel = Backbone.Model.extend({
defaults: {
lead: "not logged in",
},
url: 'test.php',
initialize: function(){
_.bindAll(this, 'handleSave', 'handleError');
// Save already knows if this.isNew.
this.save(undefined, {success: this.handleSave, error: this.handleError});
},
handleSave: function(model, response){
this.model.reset(model);
},
handleError: function(){
},
});
var HomeView = Backbone.View.extend({
initialize: function() {
_.bindAll(this, 'render');
this.model = new HomeModel();
this.model.bind("change", this.render);
},
el: 'div',
render: function() {
// Do things to render...
}
});
var homeView = new HomeView();
这个例子来自我回答的其他人的问题,我只是添加了相关内容。
一般的想法是在创建模型时保存模型,如果您在其他地方需要它,您可以将代码移动到模型的函数中,并根据事件或其他任何内容调用它。