web-dev-qa-db-ja.com

追加のパラメーターを送信するためにモデルレベルでBackbone.sync()をオーバーライドしますか?

正直に言うと、モデルのBackboneのsync()メソッドをオーバーライドしようとして立ち往生していますが、関数のシグネチャが設定されていて、正しくトリガーされますが、何を入力すればよいかわかりません。関数本体 DELETEへのデフォルトの呼び出しを行うため追加の引数を使用。すなわち。

class Master.Models.Member extends Backbone.Model
  urlRoot: '/api/members/'

  sync: (method, model, options) ->
    params = _.clone options
    Backbone.sync method, model, params

私はそれを次のように呼びます:

......
remove: ->
  @model.destroy
    collective_id: the_id

そこでの私の意図は、そこに表示されるcollective_id paramをサーバーに渡すことです。しかし、sync()のオプションハッシュの中にあり、私がそれを複製したとしても、サーバーに到達しません!方法その追加のパラメーターをサーバーに送信できますか?

(そのまま、サーバーに到達するのはモデルのIDだけです)

前もって感謝します!

24
jlstr

.destroy()、. fetch()、または.save()を呼び出すと、Backbone.syncのみを呼び出すModel.syncが呼び出されます。プロキシ機能です。これは、単一のモデルまたはそのモデルから拡張されたモデルのAJAX動作を変更するためのniceフックを提供することを意図しています。

  • ソリューション1:グローバルBackbone.syncを_JSON.stringify_にオーバーライドし、データを指定したらcontentTypeを変更します削除リクエストとともに送信されます。
    • 長所:model.destroy()を呼び出し、オプションでoptionsパラメーターを渡すことができます
  • ソリューション2-Model.syncメソッドをオーバーライドします。
    • 長所:オーバーライドは個々のモデルにのみ影響します。孤立した変更。
    • 短所:データとともに削除するすべてのモデルは、正しい「ベースモデル」から拡張する必要があります
  • ソリューション3-何もオーバーライドせず、stringifycontentTypeのすべてを使用してmodel.syncを明示的に呼び出します。
    • 長所:非常に孤立した変更で、他のモデルには影響しません。大規模なコードベースと統合する場合に役立ちます。

[ソリューション1]-Backbone.syncのグローバルオーバーライド(これはすべてのモデルに影響します)

javacriptバージョン

_var oldBackboneSync = Backbone.sync;
Backbone.sync = function( method, model, options ) {
    // delete request WITH data
    if ( method === 'delete' && options.data ) {
        options.data = JSON.stringify(options.data);
        options.contentType = 'application/json';
    } // else, business as usual.
    return oldBackboneSync.apply(this, [method, model, options]);
}
_

使用法

_var model, SomeModel = Backbone.Model.extend({ /* urlRoot, initialize, etc... */});
model = new SomeModel();
model.destroy({
    data: {
        /* data payload to send with delete request */
    }
});
_

[ソリューション2]-基本モデルのBackbone.destroyをオーバーライドし、そこから他のモデルを拡張します。

オーバーライド

_// Create your own 'enhanced' model 
Backbone.EnhancedModel = Backbone.Model.extend({
    destroy: function( options ) {
        if ( options.data ) {
            // properly formats data for back-end to parse
            options.data = JSON.stringify(options.data);
        }
        // transform all delete requests to application/json
        options.contentType = 'application/json';
        Backbone.Model.prototype.destroy.call(this, options);
    }
});
_

使用量

_var model, SomeModel = Backbone.EnhancedModel.extend({ /* urlRoot, initialize, etc... */})
model = new SomeModel();
SomeModel.destroy({
    data: {
        /* additional data payload */
    }
}); 
_

[ソリューション3]-正しいパラメータを使用して.destroy()を呼び出します。

破棄リクエストでデータを送信することが孤立したものである場合、これは適切なソリューションです。

model.destroy()を呼び出すときは、次のようにdataおよびcontentTypeオプションを渡します。

javascript version/usage

_var additionalData = { collective_id: 14 };
model.destroy({
    data: JSON.stringify(additionalData),
    contentType: 'application/json'
});
_

「問題」(ソリューションではなくバックボーンを使用):

Backbone.jsは、削除要求がデータペイロードを持たないと仮定( ソースを表示 )します。

_// delete methods are excluded from having their data processed and contentType altered.
if (options.data == null && model && (method === 'create' || method === 'update' || method === 'patch')) {
      params.contentType = 'application/json';
      params.data = JSON.stringify(options.attrs || model.toJSON(options));
}
_

想定されるRESTful API呼び出しで必要なデータは、urlRootプロパティに追加する必要があるIDのみです。

_var BookModel = Backbone.Model.extend({
    urlRoot: 'api/book'
});
var book1 = new BookModel({ id: 1 });
book1.destroy()
_

削除リクエストは次のように送信されます

_DELETE => api/book/1
contentType: Content-Type:application/x-www-form-urlencoded; charset=UTF-8
_
44
Cory Danielson

パラメータはoptions.dataで送信する必要があるため、以下を試してください。

コーヒースクリプト

remove: () ->
  @model.destroy 
    data: JSON.stringify
      collective_id: the_id, 
    contentType: 'application/json'

javaScript

remove: function() {
  return this.model.destroy({
    data: JSON.stringify({
      collective_id: the_id
    }),
    contentType: 'application/json'
  });
}
4
glortho