Backbone.js为创建和更新建模不同的url?

时间:2012-01-04 18:08:59

标签: rest backbone.js

假设我有一个Backbone模型,我创建了一个这样的模型实例:

var User = Backbone.Model.extend({ ... });
var John = new User({ name : 'John', age : 33 });

当我使用John.save()第二次使用/user/create(更新/ PUT)定位John.save()时,我想知道是否可以使用/user/update定位John.fetch() /user/get定位John.remove()以及当我使用/user/remove定位John.url

我知道每次触发任何方法之前我都可以定义/user/handle,但我想知道是否可以自动实现某些方法而不会覆盖任何Backbone方法。

我知道我可以使用一个类似{{1}}的网址并根据请求方法处理请求(GET / POST / PUT / DELETE)但我只是想知道是否有办法让每个网址不同Backbone中的行动。

谢谢!

5 个答案:

答案 0 :(得分:78)

Backbone.Model上的方法.fetch().save().destroy()正在检查模型是否已定义.sync(),如果是,则会调用{{1}将被调用(参见链接源代码的最后几行)。

因此,其中一个解决方案是实现Backbone.sync()方法。

示例:

.sync()

答案 1 :(得分:2)

要进一步抽象 dzejkej的解决方案,您可以打包Backbone.sync函数来查询特定于方法的URL 的模型。

function setDefaultUrlOptionByMethod(syncFunc)
    return function sync (method, model, options) {
        options = options  || {};
        if (!options.url)
            options.url = _.result(model, method + 'Url'); // Let Backbone.sync handle model.url fallback value
        return syncFunc.call(this, method, model, options);
    }
}

然后你可以用:

定义模型
var User = Backbone.Model.extend({
    sync: setDefaultUrlOptionByMethod(Backbone.sync),
    readUrl: '/user/get',
    createUrl: '/user/create',
    updateUrl: '/user/update',
    deleteUrl: '/user/delete'
});

答案 2 :(得分:1)

您是否正在处理不符合规范或需要某种解决方法的REST实现?

相反,请考虑使用此处的emulateHTTP选项:

http://documentcloud.github.com/backbone/#Sync

否则,你可能只需要覆盖默认的Backbone.sync方法,如果你想让它变得真正疯狂,你会很高兴...但我不建议这样做。最好只使用真正的RESTful接口。

答案 3 :(得分:0)

不,你不能默认使用骨干网。您可以添加到模型中,该模型将在模型触发的每个事件上更改模型URL。但是你总是遇到问题,bckbone将在第一次保存模型时添加POST,并在之后的每次调用中添加PUT。因此,您还需要覆盖save()方法或Backbone.sync

毕竟这样做似乎不是一个好主意,因为它打破了Backbone构建的REST模式。

答案 4 :(得分:0)

我受到了this解决方案的启发,你只需要为那些不用于获取模型的方法创建自己的ajax调用。这是它的精简版:

var Backbone = require("backbone");
var $ = require("jquery");
var _ = require("underscore");

function _request(url, method, data, callback) {
  $.ajax({
    url: url,
    contentType: "application/json",
    dataType: "json",
    type: method,
    data:  JSON.stringify( data ),
    success: function (response) {
      if ( !response.error ) {
        if ( callback && _.isFunction(callback.success) ) {
          callback.success(response);
        }
      } else {
        if ( callback && _.isFunction(callback.error) ) {
          callback.error(response);
        }
      }
    },
    error: function(mod, response){
      if ( callback && _.isFunction(callback.error) ) {
        callback.error(response);
      }
    }
  });
}

var User = Backbone.Model.extend({

  initialize: function() {
    _.bindAll(this, "login", "logout", "signup");
  },

  login: function (data, callback) {
    _request("api/auth/login", "POST", data, callback);
  },

  logout: function (callback) {
    if (this.isLoggedIn()) {
      _request("api/auth/logout", "GET", null, callback);
    }
  },

  signup: function (data, callback) {
    _request(url, "POST", data, callback);
  },

  url: "api/auth/user"

});

module.exports = User;

然后你可以像这样使用它:

var user = new User();

// user signup
user.signup(data, {
  success: function (response) {
    // signup success
  }
});

// user login
user.login(data, {
  success: function (response) {
    // login success
  }
});

// user logout
user.login({
  success: function (response) {
    // logout success
  }
});

// fetch user details
user.fetch({
  success: function () {
    // logged in, go to home
    window.location.hash = "";
  },
  error: function () {
    // logged out, go to signin
    window.location.hash = "signin";
  }
});