1. ホーム
  2. javascript

[解決済み] Backbone.jsのモデルデータを保存する方法は?

2023-04-23 23:06:06

質問

私はフロントエンドの開発が好きで、最近自分のアプリにBackbone.jsを取り入れ始めました。私はモデルのデータをサーバーに永続化したいです。

モデルデータを保存するための様々な方法(json形式を使用)を説明していただけませんか?私は、サーバー側でJavaを使用しています。また、私は主にデータを保存するために使用されるRESTを見てきました。私はフロントエンドの開発に精通しているため、RESTやその他の類似のものについては認識していません。

誰かが私にいくつかの簡単な例でプロセスを説明することができれば、それは素晴らしいことです。

どのように解決するのですか?

基本的にモデルは、特定のモデルが持つかもしれない様々な値である、属性と呼ばれるプロパティを持っています。バックボーンは、JSONオブジェクトを取る様々なメソッドを使用して、これらの値を入力する簡単な方法として、JSONオブジェクトを使用します。例を挙げます。

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

モデルに値を入れるには、いくつかの方法があります。例えば、JSONを渡してモデルのインスタンスを設定したり、属性のJSONオブジェクトを受け取るset()と呼ばれるメソッドを使用したりすることができます。

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リクエストのセマンティクスと、データで何をしているのかについて理解することが必要です。

あなたはおそらく2種類のHTTPリクエストに慣れています。GET と POST です。RESTful環境では、これらの動詞は、Backboneが想定する特定の用途のために特別な意味を持ちます。サーバーから特定のリソース(例えば前回保存したドーナツモデル、ブログのエントリ、コンピュータの仕様書)を取得したいとき、そのリソースが存在する場合は、GETリクエストを実行します。逆に、新しいリソースを作りたいときはPOSTを使う。

Backboneに触れるまで、以下の2つのHTTPリクエストメソッドは触ったことすらありませんでした。PUTとDELETEです。この2つの動詞も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にDELETEしたら、私のシステムからそれをパージすることになります。

POSTでは、まだリソースを作成していないため、確立されたリソースIDを持ちません。リソースを作成するためのURIターゲットは、単にこれだけかもしれません。

http://localhost:8888/donut

URIにIDの断片がない。これらのURIデザインはすべて、あなたのリソースについてどう考えるかはあなた次第です。しかし、RESTfulデザインに関して、私の理解では、HTTPリクエストにアクションの動詞を、URIを読みやすく、人間に優しいものにするリソースを名詞として維持したいのです。

まだ私と一緒にいるんですか?)

では、Backboneについて考えることに戻りましょう。Backboneが素晴らしいのは、多くの作業を代わりにやってくれるからです。ドーナツとsecondHelpingを保存するためには、単純にこうすればいいのです。

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

Backboneは賢いです。ドーナツリソースを作成した場合、サーバーからのIDを持ちません。これはBackboneが内部で使用しているcIDと呼ばれるものを持っていますが、公式の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は3番目のHelpingを以下の場所でGETします。 http://localhost:8888/donut/15 これは、単にあなたのサイトルートに/donutの幹を追加します。

もしあなたがまだ私と一緒にいるのなら、良いことです。私は思います。混乱してないなら。しかし、いずれにせよ、私たちは踏ん張ります。第二部はサーバー側です。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のような大きなフレームワークも似たようなことをやっていると思いますが、私はミニマルが好きです。私は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オブジェクトを想定していることです。常にサーバーにcontent-typeを'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の保存、RESTful動詞、サーバーサイドのアクション、レスポンスに関する基本的な考え方はここにあります。Backboneのドキュメント(他のドキュメントに比べると非常に読みやすい)を読み続けながら、これを理解するのに時間がかかることを心に留めておいてください。しかし、このことは頭の中を整理するのに時間がかかるということを覚えておいてください。私は毎日Backboneで新しいことを学んでいますが、このフレームワークで飛躍し、流暢になっていくのを見ると、本当に楽しくなります。)

EDIT: 役に立ちそうなリソース

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-tips