15

私はこれを機能させるために何日も試みてきましたが、コレクションに属するモデル (モデルのデータのフェッチを開始するための url 属性を適切に持っている) を破棄するというビューを持っているときに、理由がわかりません。リストビューで簡単にバインドできるように、コレクションにバブルアップされる破棄「イベント」を発生させます。ただし、実際の DELETE 要求やサーバーへの要求はまったく送信されません。どこを見ても、コレクションの url 属性、またはモデルがコレクションに接続されていない場合は urlRoot のいずれかを使用している全員がいます。実際の this.model.destroy() の前にテストして、モデルを確認しました < console.log(this.model.url());

バックボーンの destroy メソッドも sync メソッドも上書きしていません。また、各モデルには、(データベース レコードからの) コレクションのフェッチを介して入力される id 属性があります。

破棄はリスト アイテム ビューで行われ、コレクションの「破棄」イベントはリスト ビューにバインドされます。すべてうまく機能しますが (イベント処理)、ここでも問題は、サーバーへの要求がないことです。

backbone.js が自動的にそれを行うことを望んでいました。それはドキュメントが意味することであり、あらゆる場所にある多数の例と同様です。

有益な情報を提供してくれる人に感謝します。

参考までに: 私は 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);
    }

});

PS.. 繰り返しますが、他の場所から参照されているコードがあります。ただし、注意してください: コレクションには url 属性が設定されています。また、最初のフェッチだけでなく、モデルに加えられた変更を保存するために変更イベントが発生した場合にも機能します。しかし、リスト項目ビューの destroy イベントは、「destroy」イベントを正常にトリガーしますが、「DELETE」HTTP 要求を送信しません。

4

1 に答える 1

41

あなたのモデルは ID を持っていますか? そうでない場合、HTTP 要求は送信されません。– nikoshr 5 月 14 日 18:03

本当にありがとう!Nikoshr のちょっとしたコメントは、まさに私が必要としていたものでした。私はこれをいじって最後の5時間を費やしました。モデルのデフォルトに id を追加するだけでした。

于 2012-12-22T22:30:51.253 に答える