如何使用 Backbone.js 生成模型 ID
Posted
技术标签:
【中文标题】如何使用 Backbone.js 生成模型 ID【英文标题】:How to generate model id's with Backbone.js 【发布时间】:2012-06-03 04:10:57 【问题描述】:我正在设置主干同步机制,有点困惑在哪里为模型生成 id。
当我创建一个新模型时,主干是否应该生成和设置 id,或者我应该实现一个 id 生成方法,或者是否有某种机制可以将数据“PUT”到服务器,从而生成id 并返回一个带有 id 的模型?
【问题讨论】:
您(可以)手动分配它。 Backbone 在内部将cid
分配给未保存到服务器的模型元素。保存后,您返回主干用于分配给模型的元素的id
。请参阅文档 (backbonejs.org/#Model-id) 或 @orangewrap 的精美答案 :)
【参考方案1】:
我提供了第二个答案,以简化您需要研究的代码,以获得您正在思考的要点 - 从模型到服务器的实际循环以及 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 是您的数据库(或本地存储或其他解决方案)的工作。大多数情况下,这来自资源 ID 本身,也就是您的模型在某个表中的主键 ID。
通过我的设置,我使用 php 和 mysql。我会有一个名为 Dinosaur 的表,每一行都是我的恐龙模型的持久表示。所以我有一个 id 列(唯一的自动递增 int)和cavemanEater(bool)。
数据通信流程是这样发生的。
-
您创建一个模型。
模型是新的,所以它只有一个 cID - 没有正确的 ID。
您保存模型。
模型的 json 表示已发送到您的服务器 (POST)
您的服务器将其保存到表中并为其提供资源 ID。
您的服务器发回数据 id:uniqueID 的 json 表示
Backbone 接收到这个带有 id 的 json 表示
Backbone 使用 id 自动更新您的模型。
这是带注释的代码的样子。
客户:
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
服务器:
// 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 新模型和 PUT 已经有资源 id 的模型。
下次你这样做时:
tRex.save();
Backbone 将向以下 URL 发出 PUT 请求。
http://www.example.com/dino/1
顺便说一句,这是默认行为。但是您会注意到 URL 与保存不同。在服务器上,您需要一个接受 /dino/:id 而不是 /dino
的路由默认情况下,它会为您的模型使用 /urlRoot/:id 路由模式,除非您另行调整。
不幸的是,恐龙已经灭绝了。
tRex.destroy();
这将调用...你能猜到吗?是的。对 /dino/1 的删除请求。
您的服务器必须区分对不同路由的不同请求才能使 Backbone 工作。有几种服务器端技术可以做到这一点。
如果您使用 Ruby,有人提到了 Sinatra。就像我说的,我使用 PHP,我使用 SLIM PHP Framework。它的灵感来自 Sinatra,所以很相似,我喜欢它。作者写了一些干净的代码。不过,这些 RESTful 服务器实现的工作原理超出了本次讨论的范围。
我认为这是没有 id 的新 Backbone 数据的基本完整传输,通过 Internet 到它生成的服务器,然后发回资源 id,让你的模型从此过上幸福的生活。 (或者destroy()
不是……)
我不知道这对你来说是否太初学者,但希望它能帮助遇到这个问题的其他人。使用 Backbone 进行编程真的很有趣。
其他类似的答案: Ways to save Backbone JS model data
【讨论】:
顺便说一句,您实际上可以手动为模型分配 id。someModel.set('id',777);
但你为什么要这样做超出了我的范围。 :-)
+1 解释得很漂亮。省去了我打字的麻烦:D
您的意思是 Backbone 如何自动使用数据库中的对象 ID 并将其转换为 Backbone 模型 ID?您是否使用非标准的 id 格式或其他东西?不确定这是否是您要了解的内容,但请查找关键字idAttribute
这也可能与我认为您所追求的一致……不过只是猜测。 LINK: idAttribute
@cheshireoctopus 嗯。好吧,使用唯一的对象 ID 是许多 REST 类型交互的组成部分。很难想象为什么要保存一个对象而不给它分配一个 ID。如果有其他唯一标识资源的方法,您可以将 Backbone 配置为使用该属性作为 ID 而不是传统的 id 名称。如果您手动设置 ID,问题是如何确保这些 ID 是唯一的?如果您手动设置以便客户端有某种方式来识别事物......有一个 cid 或 clientID 自动附加到骨干 obj。
见idAttribute and cid。尽管您想要.save()
和.destroy()
无法唯一识别的特定资源,但我确实担心。您可以从客户端设置 id... 只需执行 model.set('id','someID')
但问题是如果您有多个客户端 - 您如何确保唯一性?然后最后服务器仍然必须在数据库中查找并验证。在那种情况下,让数据库自动分配一个唯一ID不是更容易吗? :-) 我不确定具体细节,但也许这种情况需要一个新问题?【参考方案2】:
或者是否有某种机制让我将数据“PUT”到服务器,服务器生成 id 并返回带有 id 的模型?
有点。当您调用模型的 save 方法时,主干会生成一个 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,请记住该方法自动返回的最后一个表达式是什么。
【讨论】:
虽然所有三个答案都是正确的,但这是第一个正确的答案,也是帮助我修复代码的答案。感谢大家花时间和精力来回答这个问题,非常感谢:)【参考方案3】:我从您的问题中了解到,您希望拥有一个包含服务器上存在的模型的集合。为了将这些模型放入集合中,您必须在集合中添加调用“fetch()”。
url 可以是“/users”或类似的东西,它必须返回一个包含用户数据的对象数组。然后将数组中的每个项目传递给 UserCollection.add()。好吧,实际上它会一次通过,但你明白了。
在此之后您的集合被填充。模型上的 url 用于更新和保存单个模型。集合的 url 也将用于创建模型。 Backbone 的同步是 RESTful 的,就像 Ruby on Rails 一样。实际上,您可以在 Ruby on Rails 的文档中了解更多信息:
http://guides.rubyonrails.org/routing.html
您通常会为模型设置与控制器不同的 url。填充您的集合后,您有每个模型的 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();
例子来自我回答的别人的问题,我只是添加了相关的东西。
一般的想法是在模型创建时保存它,如果您需要它在其他地方,您可以将代码移动到模型的函数中并根据事件或其他任何内容调用它。
【讨论】:
我已经完善并更新了我的问题。我只是不确定我的模型的 id 应该来自哪里。当页面最初加载时,集合将被重置([])填充,但该数据已经包含每个模型的 id,因为它已经存在。我需要知道的是从哪里获取由于用户交互而在主干中创建的新数据的 id。 您将执行模型的“保存”操作。我会更新我的答案。以上是关于如何使用 Backbone.js 生成模型 ID的主要内容,如果未能解决你的问题,请参考以下文章
在Backbone.js视图中动态设置id和className