javascript Backbone.js model.destroy() 不发送 DELETE 请求

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10587897/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 10:23:05  来源:igfitidea点击:

Backbone.js model.destroy() not sending DELETE request

phpjavascriptajaxmodelbackbone.js

提问by oz.

I've been trying for days to get this working and I just cannot figure out why when I have my view to destroy a model which belongs to a collection (which properly has a url attribute for the beginning fetch of models' data), only fires the destroy 'event' which is bubbled up to the collection for easy binding by my list view. But it does not ever send an actual DELETE request or any request to the server at all. Everywhere I look, I see everyone using either the collection's url attr, or urlRoot if the model is not connected to a collection. I've even tested before the actual this.model.destroy() to check the model < console.log(this.model.url());

我一直在努力让这个工作好几天,但我无法弄清楚为什么当我有我的观点来销毁属于一个集合的模型(它正确地有一个用于开始获取模型数据的 url 属性),只有触发销毁“事件”,该事件冒泡到集合中,以便我的列表视图轻松绑定。但它根本不会向服务器发送实际的 DELETE 请求或任何请求。在我所看到的任何地方,我看到每个人都使用集合的 url attr 或 urlRoot(如果模型未连接到集合)。我什至在实际的 this.model.destroy() 之前测试过以检查模型 < console.log(this.model.url());

I have not overwritten the destroy nor sync methods for backbone. Also each model does have an id attribute which is populated via the collection's fetch (from database records).

我没有覆盖主干的销毁或同步方法。此外,每个模型都有一个 id 属性,该属性通过集合的提取(从数据库记录中)填充。

The destroy takes place in the list item view, and the collection's "destroy" event is bound in the list view. All that works well (the event handling), but the problem, again, is there's no request to the server.

销毁发生在列表项视图中,集合的“销毁”事件绑定在列表视图中。所有这些都运行良好(事件处理),但问题又是没有对服务器的请求。

I was hoping that backbone.js would do it automatically. That was what the documentation implies, as well as the numerous examples everywhere.

我希望backbone.js 会自动完成。这就是文档所暗示的,以及无处不在的众多示例。

Much thanks to anyone who can give some useful input.

非常感谢任何可以提供一些有用意见的人。

FYI: I'm developing on wampserver PHP 5.3.4.

仅供参考:我正在 wampserver PHP 5.3.4 上进行开发。

ListItemView = BaseView.extend({

    tagName: "li",

    className: "shipment",

    initialize: function (options) {
        _.bindAll(this);
        this.template = listItemTemplate;   
        this.templateEmpty = listItemTemplateEmpty;
    },  

    events: {
        'click .itemTag' : 'toggleData',
        'click select option' : 'chkShipper',
        'click .update' : 'update',
        'click button.delete' : 'removeItem'
    },  

    // ....

    removeItem: function() {
        debug.log('remove model');

        var id = this.model.id;

        debug.log(this.model.url());

        var options = {
            success: function(model, response) {
                debug.log('remove success');
                //debug.log(model);
                debug.log(response);
                // this.unbind();
                // this.remove();
            },
            error: function(model, response) {
                debug.log('remove error');
                debug.log(response);
            }
        };

        this.model.destroy(options);


        //model.trigger('destroy', this.model, this.model.collection, options);


    }

});


Collection = Backbone.Collection.extend({

    model: Model,

    url: '?dispatch=get&src=shipments',
    url_put : '?dispatch=set&src=shipments',

    name: 'Shipments',  

    initialize: function () {
        _.bindAll(this);
        this.deferred = new $.Deferred();
        /*
        this.fetch({
            success: this.fetchSuccess,
            error: this.fetchError
        });
        */
    },

    fetchSuccess: function (collection, response) {
        collection.deferred.resolve();
        debug.log(response);
    },

    fetchError: function (collection, response) {
        collection.deferred.reject();
        debug.log(response);
        throw new Error(this.name + " fetch failed");
    },

    save: function() {
        var that = this;
        var proxy = _.extend( new Backbone.Model(),
        {
            url: this.url_put,
            toJSON: function() {
                return that.toJSON();
            }
        });
        var newJSON = proxy.toJSON()
        proxy.save(
            newJSON,
            {
                success: that.saveSuccess,
                error: that.saveError
            }
        );
    },

    saveSuccess: function(model, response) {
        debug.log('Save successful');
    },

    saveError: function(model, response) {
        var responseText = response.responseText;
        throw new Error(this.name + " save failed");
    },

    updateModels: function(newData) {
        //this.reset(newData);
    }

});



ListView = BaseView.extend({

    tagName: "ul",

    className: "shipments adminList",

    _viewPointers: {},

    initialize: function() {
        _.bindAll(this);
        var that = this;
        this.collection;
        this.collection = new collections.ShipmentModel();
        this.collection.bind("add", this.addOne);

        this.collection.fetch({
            success: this.collection.fetchSuccess,
            error: this.collection.fetchError
        });


        this.collection.bind("change", this.save);
        this.collection.bind("add", this.addOne);
        //this.collection.bind("remove", this.removeModel);
        this.collection.bind("destroy", this.removeModel);
        this.collection.bind("reset", this.render);
        this.collection.deferred.done(function() {
            //that.render();
            that.options.container.removeClass('hide');
        });             

        debug.log('view pointers');

        // debug.log(this._viewPointers['c31']);
        // debug.log(this._viewPointers[0]);

    },

    events: {

    },

    save: function() {
        debug.log('shipments changed');
        //this.collection.save();
        var that = this;
        var proxy = _.extend( new Backbone.Model(),
        {
            url: that.collection.url_put,
            toJSON: function() {
                return that.collection.toJSON();
            }
        });
        var newJSON = proxy.toJSON()
        proxy.save(
            newJSON,
            {
                success: that.saveSuccess,
                error: that.saveError
            }
        );
    },

    saveSuccess: function(model, response) {
        debug.log('Save successful');
    },

    saveError: function(model, response) {
        var responseText = response.responseText;
        throw new Error(this.name + " save failed");
    },

    addOne: function(model) {
        debug.log('added one');
        this.renderItem(model);
        /*
        var view = new SB.Views.TicketSummary({
            model: model
        });
        this._viewPointers[model.cid] = view;
        */
    },

    removeModel: function(model, response) {
        // debug.log(model);
        // debug.log('shipment removed from collection');

        // remove from server
        debug.info('Removing view for ' + model.cid);
        debug.info(this._viewPointers[model.cid]);
        // this._viewPointers[model.cid].unbind();
        // this._viewPointers[model.cid].remove();
        debug.info('item removed');
        //this.render();
    },

    add: function() {
        var nullModel = new this.collection.model({
            "poNum" : null,
            "shipper" : null,
            "proNum" : null,
            "link" : null
        });
        // var tmpl = emptyItemTmpl;
        // debug.log(tmpl);
        // this.$el.prepend(tmpl);
        this.collection.unshift(nullModel);
        this.renderInputItem(nullModel);                
    },

    render: function () {
        this.$el.html('');
        debug.log('list view render');
        var i, len = this.collection.length;
        for (i=0; i < len; i++) {
            this.renderItem(this.collection.models[i]);
        };
        $(this.container).find(this.className).remove();

        this.$el.prependTo(this.options.container);

        return this;
    },          

    renderItem: function (model) {
        var item = new listItemView({
            "model": model
        });

        // item.bind('removeItem', this.removeModel);

        // this._viewPointers[model.cid] = item;
        this._viewPointers[model.cid] = item;
        debug.log(this._viewPointers[model.cid]);
        item.render().$el.appendTo(this.$el);
    },

    renderInputItem: function(model) {
        var item = new listItemView({
            "model": model
        });
        item.renderEmpty().$el.prependTo(this.$el);
    }

});

P.S... Again, there is code that is referenced from elsewhere. But please note: the collection does have a url attribute set. And it does work for the initial fetch as well as when there's a change event fired for saving changes made to the models. But the destroy event in the list-item view, while it does trigger the "destroy" event successfully, it doesn't send the 'DELETE' HTTP request.

PS.. 再次,有从别处引用的代码。但请注意:该集合确实有一个 url 属性集。它确实适用于初始提取以及当为保存对模型所做的更改而触发更改事件时。但是列表项视图中的销毁事件虽然成功触发了“销毁”事件,但它不会发送“删除”HTTP 请求。

回答by THenry

Do your models have an ID? If not, the HTTP request won't be sent. – nikoshr May 14 at 18:03

你的模型有ID吗?如果不是,则不会发送 HTTP 请求。– nikoshr 5 月 14 日 18:03

Thanks so much! Nikoshr's little comment was exactly what I needed. I spent the last 5 hours messing with this. I just had to add an id to the defaults in my model.

非常感谢!Nikoshr 的小评论正是我所需要的。在过去的 5 个小时里,我一直在搞这个。我只需要在我的模型中为默认值添加一个 id。