web-dev-qa-db-ja.com

コレクション全体を保存するためのベストプラクティスは?

コレクションがあり、そのモデルの多くに変更を加えたとします。単一のHTTPリクエストを使用してすべての変更を保存するための最良の方法は何ですか?

33
a paid nerd

通常、RESTバックエンドは単一インスタンスの作成/更新を処理します。オブジェクトの配列を受け入れるには、これを変更する必要があります。

そうは言っても、クライアント側では、Backbone.sync関数に直接移動する必要があります。

Backbone.sync = function(method, model, options)

この場合、モデルはモデルの配列である必要があります。メソッドは「作成」または「保存」である必要があり、オプションはjQuery ajax呼び出しと同じタイプのオプション(エラー、成功など)を取ります。

24
Julien

私はここで間違ったことをし、ウィキペディアを引用します 適切なRESTfulプラクティス :a[〜#〜] put [〜#〜]to example.com/resourcesは、コレクション全体を別のコレクションに置き換える必要があります。これに基づいて、複数のアイテムの同時編集をサポートする必要がある場合、この契約を作成しました。

  1. クライアントは{"resources": [{resource1},{resource2}]}を送信します
  2. サーバーはコレクション全体をクライアントからの新しい情報に置き換え、永続化された後に情報を返します:{"resources": [{"id":1,...},{"id":2,...}]}

契約の半分をRailsでサーバーに記述しましたが、これがクライアントの半分です(CoffeeScriptでは申し訳ありません!):

class ChildElementCollection extends Backbone.Collection
  initialize: ->
    @bind 'add', (model) -> model.set('parent_id', @parent.id)

  url: -> "#{@parent.url()}/resources" # let's say that @parent.url() == '/parent/1'
  save: ->
    response = Backbone.sync('update', @, url: @url(), contentType: 'application/json', data: JSON.stringify(children: @toJSON()))
    response.done (models) => @reset models.resources

これはlot実装が簡単で、Backbone.syncをオーバーライドすると思いました。コードに関するコメントの1つとして、コレクションは常に子オブジェクトでした。これは、オブジェクトがコレクションに追加されるたびにコードが「parent_id」を設定する理由と、URLのルートが親のURLである理由を説明する必要があります。変更するルートレベルのコレクションがある場合は、@parentビジネスを削除するだけです。

12
carpeliam

_Backbone.Collection_を拡張して、各モデルsave()をチェックするhasChanged()メソッドを指定する必要があります。

次に、_Backbone.sync_を呼び出す必要があります。これは、カスタム同期関数に少し拡張する必要があります。カスタム_Backbone.sync_関数を使用する場合は、必ずコレクションに設定してください。

_var CollectionSync = function(method, model, [options]) {
    // do similar things to Backbone.sync
}

var MyCollection = Backbone.Collection.extend({
    sync: CollectionSync,
    model: MyModel,
    getChanged: function() {
        // return a list of models that have changed by checking hasChanged()
    },
    save: function(attributes, options) {
        // do similar things as Model.save
    }
});
_

別のアプローチ(モデルを使用してコレクションを表す)は次のとおりです。 コレクション全体をBackbone.jsに保存する「方法」--Backbone.syncまたはjQuery.ajax?

私も好きです https://stackoverflow.com/a/7986982/137067

6
philfreo

このコードは、変更されたモデルのsaveメソッドを呼び出すためだけに、コレクションプロトタイプに新しいメソッドを追加します。それは私のために働いた:

Backbone.Collection.prototype.saveAll = function(options) {
 return $.when.apply($, _.map(this.models, function(m) {
   return m.hasChanged() ? m.save(null, options).then(_.identity) : m;
 }));
};

要旨リンク: https://Gist.github.com/julianitor/701c677279bac1529b88

0
juliantoledo