保存Backbone.js模型数据的方法?


86

我更喜欢前端开发,并且最近开始在我的应用程序中探索Backbone.js。我想将模型数据保存到服务器。

您能否解释一下保存模型数据的各种方式(使用json格式)。我在服务器端使用Java。我也主要看到REST用于保存数据。由于我更喜欢​​前端开发人员,因此我不了解REST和其他类似内容。

如果有人可以用一些简单的例子向我解释这个过程,那就太好了。

Answers:


272

基本上,模型具有称为属性的属性,这些属性是某个模型可能具有的各种值。Backbone使用JSON对象作为一种简单的方法,使用各种采用JSON对象的方法来填充这些值。例:

Donuts = Backbone.Model.extend({
    defaults: {
        flavor: 'Boston Cream',  // Some string
        price: '0.50'  // Dollars
    }
});

要填充模型,有几种方法可以填充。例如,您可以通过传入JSON或使用名为set()的方法来建立模型实例,该方法采用属性的JSON对象。

myDonut = new Donut({'flavor':'lemon', 'price':'0.75'});
mySecondHelping = new Donut();
mySecondHelping.set({'flavor':'plain', 'price':'0.25'});

console.log(myDonut.toJSON());
// {'flavor':'lemon', 'price':'0.75'}
console.log(mySecondHelping.toJSON());
// {'flavor':'plain', 'price':'0.25'}

因此,这使我们可以保存模型并将其持久保存到服务器中。关于“什么是REST / RESTful?”的详细信息有很多。在这里简短地解释所有这些都是有点困难的。特别是在REST和Backbone节省方面,让您大吃一惊的是HTTP请求的语义以及您对数据的处理方式。

您可能已经习惯了两种HTTP请求。GET和POST。在RESTful环境中,这些动词对于Backbone假定的特定用途具有特殊含义。当您想从服务器获取某个资源(例如,我上次保存的甜甜圈模型,博客条目,计算机规范)并且该资源存在时,您可以执行GET请求。相反,当您要创建新资源时,请使用POST。

在进入Backbone之前,我什至从未接触过以下两种HTTP请求方法。放入并删除。这两个动词对Backbone也有特定的含义。当您想要更新资源时(例如,将柠檬甜甜圈的口味更改为柠檬甜甜圈等),您可以使用PUT请求。当您要一起从服务器删除该模型时,可以使用DELETE请求。

这些基础非常重要,因为使用RESTful应用程序时,您可能会有一个URI名称,它将根据您使用的请求谓词的种类执行适当的任务。例如:

// The URI pattern
http://localhost:8888/donut/:id

// My URI call
http://localhost:8888/donut/17

如果我对该URI进行GET,它将获得ID为17的甜甜圈模型。:id取决于您如何在服务器端保存它。这可能只是数据库表中甜甜圈资源的ID。

如果我使用新数据对该URI进行PUT,则将对其进行更新并保存。如果我删除了该URI,那么它将从系统中清除它。

使用POST,由于您尚未创建资源,但它不会具有已建立的资源ID。也许我要创建资源的URI目标就是这样:

http://localhost:8888/donut

URI中没有ID片段。所有这些URI设计都取决于您以及您如何考虑资源。但是对于RESTful设计,我的理解是您希望将动作的动词保留在HTTP请求和资源中,作为使URI易于阅读和人性化的名词。

你还在吗?:-)

因此,让我们重新考虑一下Backbone。骨干网很棒,因为它可以为您完成很多工作。要保存我们的甜甜圈和secondHelping,我们只需执行以下操作:

myDonut.save();
mySecondHelping.save();

骨干很聪明。如果您只是创建了一个甜甜圈资源,那么它将没有来自服务器的ID。它有一个叫做cID的东西,这是Backbone内部使用的,但是由于它没有官方ID,它知道它应该创建一个新资源并发送POST请求。如果您是从服务器上获得模型的,那么如果一切正确,它可能会有一个ID。在这种情况下,当您保存()时,Backbone假定您要更新服务器,它将发送一个PUT。要获取特定资源,可以使用Backbone方法.fetch()并发送GET请求。当您在模型上调用.destroy()时,它将发送DELETE。

在前面的示例中,我从未明确告诉Backbone URI在哪里。让我们在下一个示例中进行操作。

thirdHelping = Backbone.Model.extend({
    url: 'donut'
});
thirdHelping.set({id:15});  // Set the id attribute of model to 15
thirdHelping.fetch();  // Backbone assumes this model exists on server as ID 15

骨干网将获得第三个帮助。http://localhost:8888/donut/15它将简单地将/ donut干添加到您的站点根目录。

如果您还是和我在一起,那就好。我认为。除非您感到困惑。但是我们还是会拖延时间。第二部分是服务器端。我们已经讨论了HTTP的不同动词以及这些动词背后的语义。这意味着您,骨干网和您的服务器必须共享。

您的服务器需要了解GET,POST,PUT和DELETE请求之间的区别。如您在上面的示例中所看到的,GET,PUT和DELETE都可以指向相同的URI,http://localhost:8888/donut/07除非您的服务器可以区分这些HTTP请求,否则在处理该资源时会非常困惑。

这是您开始考虑RESTful服务器端代码的时候。有些人喜欢Ruby,有些人喜欢.net,我喜欢PHP。特别是我喜欢SLIM PHP微框架。SLIM PHP是一个微框架,具有用于处理RESTful活动的非常优雅且简单的工具集。您可以像上面的示例中那样定义路由(URI),并根据调用是GET,POST,PUT还是DELETE来执行正确的代码。还有其他类似于SLIM的解决方案,例如Recess,Tonic。我相信较大的框架(例如Cake和CodeIgniter)也可以做类似的事情,尽管我喜欢最少的框架。我是说我喜欢Slim吗?;-)

这就是服务器上摘录代码的外观(即专门关于路由)。

$app->get('/donut/:id', function($id) use ($app) {
    // get donut model with id of $id from database.
    $donut = ...

    // Looks something like this maybe:
    // $donut = array('id'=>7, 'flavor'=>'chocolate', 'price'=>'1.00')

    $response = $app->response();
    $response['Content-Type'] = 'application/json';
    $response->body(json_encode($donut));
});

在这里重要的是要注意,Backbone需要一个JSON对象。始终让服务器将内容类型指定为“ application / json”,并尽可能以json格式对其进行编码。然后,当Backbone收到JSON对象时,它知道如何填充请求它的模型。

使用SLIM PHP,路由的运行方式与上述类似。

$app->post('/donut', function() use ($app) {
    // Code to create new donut
    // Returns a full donut resource with ID
});
$app->put('/donut/:id', function($id) use ($app) {
    // Code to update donut with id, $id
    $response = $app->response();
    $response->status(200);  // OK!
    // But you can send back other status like 400 which can trigger an error callback.
});
$app->delete('/donut/:id', function($id) use ($app) {
    // Code to delete donut with id, $id
    // Bye bye resource
});

因此,您几乎完成了整个往返行程!去拿汽水 我喜欢健怡露水。也给我买一个。

服务器处理完请求后,对数据库和资源进行处理,准备响应(无论是简单的http状态编号还是完整的JSON资源),然后数据将返回Backbone进行最终处理。

使用save(),fetch()等方法-您可以在成功和错误时添加可选的回调。这是我如何设置此特定蛋糕的示例:

Cake = Backbone.Model.extend({
    defaults: {
        type: 'plain',
        nuts: false
    },
    url: 'cake'
});

myCake = new Cake();
myCake.toJSON()  // Shows us that it is a plain cake without nuts

myCake.save({type:'coconut', nuts:true}, {
    wait:true,
    success:function(model, response) {
        console.log('Successfully saved!');
    },
    error: function(model, error) {
        console.log(model.toJSON());
        console.log('error.responseText');
    }
});

// ASSUME my server is set up to respond with a status(403)
// ASSUME my server responds with string payload saying 'we don't like nuts'

这个例子有两件事。您会看到我的蛋糕,而不是在保存之前先set()设置属性,而只是将新属性传递给保存调用。Backbone非常善于利用JSON数据,并像处理冠军一样处理它。所以我想用椰子和坚果保存我的蛋糕。(那是2个坚果吗?)无论如何,我传入了两个对象进行保存。属性JSON对象和一些选项。第一个{wait:true}表示在服务器端访问成功之前不要更新我的客户端模型。服务器成功返回响应后,将发生成功回调。但是,由于此示例导致错误(状态为200以外的其他值将指示Backbone使用错误回调),因此我们得到了没有更改的模型表示。它应该仍然是纯净的,没有坚果。我们还可以访问服务器发回的错误对象。我们发回了一个字符串,但它可能是具有更多属性的JSON错误对象。它位于error.responseText属性中。是的,“我们不喜欢坚果。”

恭喜你 您已经从建立模型,将其保存到服务器端并返回来进行了首次完整往返。我希望这个答案史诗能为您提供有关所有这些如何结合的想法。当然,我有很多细节需要探讨,但是Backbone save,RESTful动词,服务器端操作,Response的基本思想都在这里。继续阅读Backbone文档(与其他文档相比,它非常易于阅读),但请记住,这需要花费很多时间来解决。坚持得越多,就会越流利。我每天都会在Backbone上学到一些新东西,当您开始突飞猛进并看到您在此框架中的流利程度不断提高时,它会变得非常有趣。:-)

编码愉快!

编辑:可能有用的资源:

关于SO的其他类似答案: 如何使用Backbone生成模型ID

在REST上:http : //rest.elkstein.org/ http://www.infoq.com/articles/rest-introduction http://www.recessframework.org/page/towards-restful-php-5-basic-提示


9
我最终在这个问题上有些发疯。我记得当我刚开始使用Backbone时遇到了诸如提问者之类的问题,并且写出回复时我有点太开心了。我确信我匆忙犯了一些错误,或者错过了一些重要的重要“啊哈!” 如果我做了,请告诉我。:-P
jmk2142 2012年

6
至少可以说出最令人惊讶的答案...我正在尝试掌握您提到的所有内容。尽管您是对的,但REST的东西看起来有点困难,您不能肯定在这个问题内向我解释REST ...我'会再次经历并在一段时间内接受它。。。再次感谢您提供详细的答案...
testndtv 2012年

2
如果有时间,我会用一系列可以帮助您完成任务的良好参考文献来更新答案。我不能给你一把木剑来面对外​​面的危险世界,但是我可以给你提供帮助我的站点的资源链接。:-)
jmk2142 2012年

5
@testndtv我最终回答了你的问题吗?√标记将不胜感激。
jmk2142 2012年

2
毫无疑问ü没有回答超过预期的方式问题...我又接受了答案now..Thanks了很多的帮助..
testndtv
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.