简体   繁体   中英

Success Callback on Model destroy doesn't work

Here is my jsFiddle:

https://jsfiddle.net/Frankistan/dqbexhr0/1/

window.Wine = Backbone.Model.extend({
    urlRoot: "api/wines",
    defaults: {
        "id": null,
            "name": "",
            "grapes": "",
            "country": "USA",
            "region": "Wisconsin",
            "year": "",
            "description": "",
            "picture": "none.jpg"
    }
});

var WineCollection = Backbone.Collection.extend({
    model: Wine,
    url: "api/wines"
});
window.StartView = Backbone.View.extend({
    initialize: function () {
        this.template = _.template($('#start-template').html());
    },
    render: function () {
        this.$el.html(this.template());

        return this.el;
    }
});

window.HeaderView = Backbone.View.extend({
    events: {
        'click .new': 'newWine'
    },
    initialize: function () {
        this.template = _.template($('#header-template').html());
    },
    render: function () {
        this.$el.html(this.template());
        return this.el;
    },
    newWine: function () {
        debugger
        app.navigate('wines/new', true);
        return false;
    }
});

window.WineListView = Backbone.View.extend({
    tagName: 'ul',
    initialize: function () {
        this.collection.on('add', this.appendNewWine, this);
        this.collection.on('reset', this.render, this);
    },
    render: function () {
        _.each(this.collection.models, function (wine) {
            this.appendNewWine(wine);
        }, this);

        return this.el;
    },
    appendNewWine: function (wine) {
        var wineListItemView = new WineListItemView({
            model: wine
        }).render();
        this.$el.append(wineListItemView);
    }
});

window.WineListItemView = Backbone.View.extend({
    tagName: 'li',
    initialize: function () {
        this.template = _.template($('#wine-list-item-template').html());

        this.model.bind('destroy', this.remove, this);
        this.model.bind('change:name', this.render, this);

    },
    render: function () {
        console.log('ListItemView render: ');
        this.$el.html(this.template(this.model.toJSON()));

        return this.el;
    },
    update: function () {
        console.log('actualizando nombre en la lista');
        debugger
        this.$el.find('a').text(this.model.get('name'));
    }
});

window.WineDetailView = Backbone.View.extend({
    events: {
        "change input": "change",
            "click .save": "saveWine",
            "click .delete": "deleteWine"
    },
    initialize: function () {

        this.template = _.template($('#wine-details-template').html());

        this.model.bind("destroy", this.remove, this);
    },
    render: function () {
        console.log('DetailView render: ');
        this.$el.html(this.template(this.model.toJSON()));

        return this.el;
    },
    saveWine: function () {
        // version 1
        var self = this;

        this.model.set({
            name: $('#name').val(),
            grapes: $('#grapes').val(),
            country: $('#country').val(),
            region: $('#region').val(),
            year: $('#year').val(),
            description: $('#description').val()
        });

        if (this.model.isNew()) {

            this.model.save({
                wait: true
            }, {
                success: function (wine, reponse, options) {
                    app.wineList.add(wine);
                    Backbone.history.navigate('wines/' + self.model.id, {
                        trigger: true
                    });

                }
            });
        } else {
            this.model.save();
        }

        return false;
    },
    deleteWine: function () {
        debugger
        var options = {
            success: function (model, response) {
                console.log('delete wine success');
                console.log(model);
                console.log(response);
            },
            error: function (model, response) {
                console.log('delete wine error');
                console.log(response);
            }
        };
        this.model.destroy(options);
    },
    change: function (event) {
        var target = event.target;
        console.log('changing ' + target.id + ' from: ' + target.defaultValue + ' to: ' + target.value);
    }
});
var AppRouter = Backbone.Router.extend({
    initialize: function () {
        $('#header').html(new HeaderView().render());
    },

    routes: {
        "": "list",
            "wines/new": "newWine",
            "wines/:id": "wineDetails"
    },

    list: function () {
        this.before(function () {
            this.showView('#content', new StartView());
        });
    },

    wineDetails: function (id) {
        this.before(function () {
            var wine = this.wineList.get(id);
            this.showView('#content', new WineDetailView({
                model: wine
            }));
        });
    },

    newWine: function () {
        this.before(function () {
            this.showView('#content', new WineDetailView({
                model: new Wine()
            }));
        });
    },

    showView: function (selector, view) {
        if (this.currentView) this.currentView.close();

        $(selector).html(view.render());
        this.currentView = view;

        return view;
    },

    before: function (callback) {
        if (this.wineList) {
            if (callback) callback.call(this);
        } else {
            this.wineList = new WineCollection();
            var self = this;
            this.wineList.fetch({
                success: function (collection, response, options) {
                    var winelist = new WineListView({
                        collection: collection
                    }).render();
                    $('#sidebar').html(winelist);
                    if (callback) callback.call(self);
                }
            });
        }
    }

});

Backbone.View.prototype.close = function () {
    // console.log('Closing view ' + this);
    if (this.beforeClose) {
        this.beforeClose();
    }
    this.remove();
    this.off();
};

$(document).ready(function () {
    app = new AppRouter();
    if (!Backbone.history.started) {
        // Backbone.history.start({ pushState: true });
        Backbone.history.start();
    }
});

everythings works fine but when I destroy a model by clicking ".delete" button, as you can see at lines from 137 to 151, the "deletewine" function is fired and although the model is deleted on the server (200 response), success callback is not fired!!

Any idea what could be the problem??

I can not run your fiddle and I don't know what is your server side code. but i guess value returned from your server side code is not right.

it's response should be a json(any json hash). for example it can return: {success: true} maybe your code returns nothing?

you can also tell backbone not to expect any response from server:

deleteWine: function () {
    debugger
    var options = {
        contentType: false, 
        processData: false,
        success: function (model, response) {
            console.log('delete wine success');
            console.log(model);
            console.log(response);
        },
        error: function (model, response) {
            console.log('delete wine error');
            console.log(response);
        }
    };
    this.model.destroy(options);
}

please take a look at this question .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM