3

Backbone.js モデルでカスタム更新機能を実現する「正しい」方法を見つけようとしています。私がやろうとしていることの例は次のとおりです。

var Cat = Backbone.Model.extend({

  defaults: {
    name     : 'Mr. Bigglesworth',
    location : 'Living Room',
    action   : 'sleeping'
  },

  sleep: function () {
    // POST /cats/{{ cat_id }}/action
    // { action: "sleep" }
  },

  meow: function () {
    // POST /cats/{{ cat_id }}/action
    // { action: "meow" }
  }

})

私が知る限り、このBackbone.Collection.save()メソッドは次のことのみを実行します。

POST /cats/{{ cat_id }}
{ name: 'Mr. Bigglesworth', location: 'Living Room', action: '{{ value }} '}

actionしかし、私が使用している API では、そのように変更することはできません。

POST /cats/{{ cat_id }}/action
{ action: "{{ value }}" }

うまくいけば、それは理にかなっていますか?

どんな助けでも大歓迎です。

4

2 に答える 2

4

save を呼び出すときに、URL をパラメーターとして渡すことができます。多分あなたはこのようなことをすることができます:

var Cat = Backbone.Model.extend({
  urlRoot: '/cats/',

  defaults: {
    name     : 'Mr. Bigglesworth',
    location : 'Living Room',
    action   : 'sleeping'
  },

  sleep: function () {
    var custom_url = this.urlRoot + this.id + "/action";
    this.save({}, { url: custom_url});
    // POST /cats/{{ cat_id }}/action
    // { action: "sleep" }
  },
});

ここを参照してください: URL パラメーターを渡すために .save() を使用してフォーム データを投稿する

更新時に常にカスタム URL を使用する場合は、sync メソッドを実装して別の URL を使用することもできます。たとえば、ここを参照してください: backbone.js は、モデルの保存とフェッチに異なる URL を使用します

于 2013-05-13T19:54:42.133 に答える
3

これを解決するにはさまざまな方法がありますが、IMO で最もクリーンな方法は、Backbone.sync をオーバーライドして、接続先のサーバー バックエンドに対してユニバーサルである場合に、希望どおりに動作させることです。

たとえば、すべてのモデル/コレクションを特定のバックエンド実装とやり取りする場合、このアプローチは非常に理にかなっています。

このようにして、残りのコレクション (またはモデル) コードをバックボーンのデフォルトのままにしておくことができますが、希望どおりに機能します。

例えば:

// Store the default Backbone.sync so it can be referenced later
Backbone.vanillaSync = Backbone.sync;

// Most of this is just copy-pasted from the original Backbone.sync
Backbone.sync = function(method, model, options) {
    var type = methodMap[method];

    // Default options, unless specified.
    _.defaults(options || (options = {}), {
      emulateHTTP: Backbone.emulateHTTP,
      emulateJSON: Backbone.emulateJSON
    });

    // Default JSON-request options.
    var params = {type: type, dataType: 'json'};

    // Ensure that we have a URL.
    if (!options.url) {
      params.url = _.result(model, 'url') || urlError();
    }

    // START ADD YOUR LOGIC HERE TO ADD THE /action

    // Add the action to the url
    params.url = params.url + '/' + options.action;

    // Remove the action from the options array so it isn't passed on
    delete options.action;

    // END ADD YOUR LOGIC HERE TO ADD THE /action    

    // Ensure that we have the appropriate request data.
    if (options.data == null && model && (method === 'create' || method === 'update' || method === 'patch')) {
      params.contentType = 'application/json';
      params.data = JSON.stringify(options.attrs || model.toJSON(options));
    }

    // For older servers, emulate JSON by encoding the request into an HTML-form.
    if (options.emulateJSON) {
      params.contentType = 'application/x-www-form-urlencoded';
      params.data = params.data ? {model: params.data} : {};
    }

    // For older servers, emulate HTTP by mimicking the HTTP method with `_method`
    // And an `X-HTTP-Method-Override` header.
    if (options.emulateHTTP && (type === 'PUT' || type === 'DELETE' || type === 'PATCH')) {
      params.type = 'POST';
      if (options.emulateJSON) params.data._method = type;
      var beforeSend = options.beforeSend;
      options.beforeSend = function(xhr) {
        xhr.setRequestHeader('X-HTTP-Method-Override', type);
        if (beforeSend) return beforeSend.apply(this, arguments);
      };
    }

    // Don't process data on a non-GET request.
    if (params.type !== 'GET' && !options.emulateJSON) {
      params.processData = false;
    }    

    // If we're sending a `PATCH` request, and we're in an old Internet Explorer
    // that still has ActiveX enabled by default, override jQuery to use that
    // for XHR instead. Remove this line when jQuery supports `PATCH` on IE8.
    if (params.type === 'PATCH' && window.ActiveXObject &&
      !(window.external && window.external.msActiveXFilteringEnabled)) {
      params.xhr = function() {
        return new ActiveXObject("Microsoft.XMLHTTP");
      };
    }

    // Make the request, allowing the user to override any Ajax options.
    var xhr = options.xhr = Backbone.ajax(_.extend(params, options));
    model.trigger('request', model, xhr, options);
    return xhr;
};

上記の例では、オプション配列を介してアクションを送信したと仮定しました。実際に静的な単語/actionが必要な場合は、そのブロックを次のように置き換えることができます。

// Add the action to the url
params.url = params.url + '/action';

これにより、残りのコードをクリーンに保ちながら、最もクリーンな実装が得られるはずです。

于 2013-05-13T19:59:00.553 に答える