如何使用Backbone.js生成模型ID

时间:2012-05-28 21:34:19

标签: backbone.js

我正在设置骨干同步机制,并且有点困惑在哪里为模型生成id。

当我创建一个新模型时,骨干应该生成并设置id,还是我应该实现一个id生成方法,或者是否存在某种机制,我将数据“输出”到服务器,生成id并返回一个带有id?

的模型

3 个答案:

答案 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)。

数据通信流程就是这样发生的。

  1. 您创建了一个模型。
  2. 该模型是新的,因此它只有一个cID - 没有正确的ID。
  3. 您保存模型。
  4. 您的模型的json表示是SENT到您的服务器(POST)
  5. 您的服务器将其保存到表中并为其提供资源ID。
  6. 您的服务器SENDS返回数据{id:uniqueID}
  7. 的json表示形式
  8. Backbone以id
  9. 接收此json表示
  10. Backbone使用id自动更新您的模型。
  11. 以下是带注释的代码。

    客户端:

    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请求。

    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服务器实现的工作方式不在本讨论的范围之内。

    我认为这是新的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();

这个例子来自我回答的其他人的问题,我只是添加了相关内容。

一般的想法是在创建模型时保存模型,如果您在其他地方需要它,您可以将代码移动到模型的函数中,并根据事件或其他任何内容调用它。