【问题标题】:Ways to save Backbone.js model data?保存 Backbone.js 模型数据的方法?
【发布时间】:2012-04-06 15:50:05
【问题描述】:

我更喜欢前端开发,最近开始在我的应用中探索 Backbone.js。我想将模型数据持久化到服务器。

能否请您解释一下保存模型数据的各种方法(使用 json 格式)。我在服务器端使用 Java。此外,我主要看到 REST 用于保存数据。由于我更喜欢​​前端开发,所以我不知道 REST 和其他类似的东西。

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

【问题讨论】:

    标签: javascript json backbone.js javascript-framework


    【解决方案1】:

    基本上,模型具有称为属性的属性,它是某个模型可能具有的各种值。 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 请求。获取和发布。在 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。 Backbone 很棒,因为它为您做了很多工作。为了节省我们的甜甜圈和 secondHelping,我们只需这样做:

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

    Backbone 很聪明。如果您刚刚创建了一个甜甜圈资源,它不会有来自服务器的 ID。它有一个叫做 cID 的东西,这是 Backbone 在内部使用的,但由于它没有官方 ID,它知道它应该创建一个新资源并发送一个 POST 请求。如果您从服务器获取模型,如果一切正常,它可能会有一个 ID。在这种情况下,当您 save() 时,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
    

    Backbone 将在http://localhost:8888/donut/15 获得第三个帮助,它只会将 /donut stem 添加到您的站点根目录。

    如果你还在我身边,很好。我想。除非你很困惑。但无论如何,我们都会艰难前行。第二部分是服务器端。我们已经讨论了 HTTP 的不同动词以及这些动词背后的语义含义。您、Backbone 和您的服务器必须共享的含义。

    您的服务器需要了解 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 这样更大的框架也会做类似的事情,尽管我喜欢最小化。我有说我喜欢斯利姆吗? ;-)

    这是服务器上的摘录代码可能看起来的样子(即专门关于路由。)

    $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 对象。始终让您的服务器将内容类型指定为“应用程序/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
    });
    

    所以您几乎完成了完整的往返行程!去喝苏打水。我喜欢Diet Mountain Dew。也给我买一个。

    一旦您的服务器处理了一个请求,对数据库和资源进行处理,准备一个响应(无论是简单的 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 数据并像冠军一样处理它方面是相当的忍者。所以我想用椰子和坚果来保存我的蛋糕。 (那是两个坚果吗?)无论如何,我将两个对象传递给我的保存。属性 JSON 对象和一些选项。第一个,{wait:true} 意味着在服务器端旅行成功之前不要更新我的客户端模型。当服务器成功返回响应时,将发生成功回调。但是,由于此示例导致错误(200 以外的状态将指示 Backbone 使用错误回调),我们得到了没有更改的模型表示。它应该仍然是简单的,没有坚果。我们还可以访问服务器发回的错误对象。我们发回了一个字符串,但它可能是具有更多属性的 JSON 错误对象。这位于 error.responseText 属性中。是的,“我们不喜欢坚果。”

    恭喜。您已经完成了从设置模型、保存服务器端到返回的第一次完整的往返旅程。我希望这个答案史诗能给你一个关于这一切如何结合在一起的想法。当然,有很多细节我都在游弋过去,但 Backbone 保存、RESTful 动词、服务器端操作、响应的基本思想都在这里。继续阅读 Backbone 文档(与其他文档相比,它非常容易阅读),但请记住,这需要时间来理解。你越坚持,你就会越流利。我每天都通过 Backbone 学到一些新东西,当你开始飞跃并看到你在这个框架中的流利程度不断提高时,它变得非常有趣。 :-)

    编辑:可能有用的资源:

    关于 SO 的其他类似答案: How to generate model IDs with Backbone

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

    【讨论】:

    • 很高兴看到这个答案在这么久之后仍然很强大。如果您喜欢 Backbone,如果您想使用 BaaS(后端即服务),还应该查看 Parse.com。他们的 API 是 Backbone 框架的一个分支。
    猜你喜欢
    • 2012-08-25
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 2012-03-27
    • 1970-01-01
    • 2011-09-17
    • 2012-11-18
    • 2012-04-17
    相关资源
    最近更新 更多