1

TL;DR 版本:

使用 Backbone 构建一个 Phonegap 应用程序,并有一个名为 Client 的模型和一个名为 Clients 的集合。使用 Tastypie API 与单独的服务器通信。当我运行fetch()时,URL 使用正确的绝对 URL(类似于http://127.0.0.1:8000/api/v1/client/1/,但是当我运行时Client.destroy(),它使用 的相对 URL 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 按钮,因此每次单击其中一个按钮时都会执行 deleteclient 函数。我还使用backbone-tastypie 来消除Backbone 和Tastypie 之间的不一致。

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

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

4

2 回答 2

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...
});
于 2013-07-11T15:07:49.177 回答
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(),那么就可以了。我找不到更干燥的方法来做这件事有点烦人,所以我愿意接受任何其他方法来做同样的事情。

于 2013-07-11T13:32:01.080 回答