Backbone DELETE请求的基本URL不正确 - 使用相对而不是绝对URL

时间:2013-07-11 10:53:38

标签: django backbone.js cordova tastypie

TL; DR版本:

使用Backbone构建Phonegap应用程序,并拥有一个名为Client的模型和一个名为Clients的集合。使用Tastypie API与单独的服务器通信。当我运行fetch()时,网址会使用正确的绝对网址(类似http://127.0.0.1:8000/api/v1/client/1/),但是当我运行Client.destroy()时,它会使用file:///api/v1/client/1/的相对网址。我该怎么办?让它使用绝对URL来删除对象吗?

长版:

我正在使用Backbone.js构建一个使用Django / Tastypie API的移动应用程序,而且我遇到了一些看似奇怪的行为,我无法弄清楚。

我在文件顶部定义了服务器的基本URL:

// Set the base URL for querying the API
baseUrl = 'http://127.0.0.1:8000/api/v1/';

我有以下型号和系列:

// Client model
Client = Backbone.Model.extend({

    urlRoot: baseUrl + 'client',

    // Default values
    defaults: {
        id: '',
        name: '',
        mobile: '',
        email: '',
        notes: '',
        operator: '',
        date_client_joined: '',
        address: '',
        postcode: ''
    }
});

// Client collection
Clients = Backbone.Collection.extend({

    // Will hold Client objects
    model: Client,

    // Set URL
    url: baseUrl + 'client/'
});

使用以下视图将各个客户端呈现在列表中:

// Client list item view
ClientListItemView = Backbone.View.extend({
    tagName: 'li',

    events: {
        'click .delete': 'deleteclient'
    },

    render: function () {
        // Render the client list item template
        var template = _.template($('#client-list-item-template').html());
        this.$el.html(template(this.model.toJSON()));

        // Return the object
        return this;
    },

    deleteclient: function () {
        this.model.destroy();
        return false;
    }
});

现在,应用程序实际上使用jQuery Mobile,每个客户端旁边都有一个Delete按钮,并带有一个delete类,因此每次单击其中一个按钮时都会执行deleteclient函数。我也使用骨干 - tastypie来消除Backbone和Tastypie之间的不一致。

deleteclient函数正在运行,但是它将HTTP DELETE请求发送到相对URL file:///api/v1/client/1/(因为这是一个Phonegap应用程序,我只是在本地查看文件)。从文档设置urlRoot手动似乎是要走的路,但这样做似乎并没有解决问题。运行fetch()函数来填充集合的工作非常正常 - 但它使用了正确的绝对URL。

所以,我的问题是如何覆盖默认行为并确保我的HTTP DELETE请求被发送到正确的URL?

2 个答案:

答案 0 :(得分:1)

通过查看您的代码,它应该可以正常工作。骨干中的模型已经定义了url()函数,应该这样做:

url: function() {
  var base = _.result(this, 'urlRoot') || _.result(this.collection, 'url') || urlError();
  if (this.isNew()) return base;
  return base + (base.charAt(base.length - 1) === '/' ? '' : '/') + encodeURIComponent(this.id);
},

您可以使用调试器查看它是否进入此代码内部,结果是什么?主要检查_.result()来电...

中的值

无论如何,您可以覆盖模型中的url属性,而不是在每次调用destroy()时传递它:

Client = Backbone.Model.extend({
    url: function () { return baseUrl + 'client/' + this.id + '/'; }
    // other code...
});

答案 1 :(得分:0)

我找到了一个解决方案,虽然我对此并不满意:

    deleteclient: function () { 
        if (confirm('Are you sure you wish to delete this client?')) {
            // Destroy the model
            this.model.destroy({
                url: baseUrl + 'client/' + this.model.get('id') + '/'
            });  

            // Remove the view
            this.remove();
        }    
    } 

基本上,如果我明确地将URL传递给destroy(),那就可以了。有点烦人的是我找不到更干的方法来做这件事,所以我对任何其他做同样事情的方法持开放态度。