javascript - 模型销毁成功回调不起作用

标签 javascript jquery backbone.js

这是我的 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();
    }
});

一切正常,但是当我通过单击“.delete”按钮销毁模型时,正如您在第 137 行到 151 行中看到的那样,“deletewine”函数被触发,尽管模型已在服务器上删除(200 响应),成功回调不会被触发!!

知道可能是什么问题吗?

最佳答案

我无法运行你的 fiddle ,我不知道你的服务器端代码是什么。 但我猜你的服务器端代码返回的值不正确。

它的响应应该是一个 json(任何 json 哈希值)。例如它可以返回: {success: true} 也许您的代码什么也没有返回?

您还可以告诉 Backbone 不要期待服务器的任何响应:

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);
}

请查看this question .

关于javascript - 模型销毁成功回调不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29200430/

相关文章:

javascript - 我可以将来自 Google API 的 XML 存储在 Javascript 中作为字符串吗?

javascript - 对象的属性是否存储在其原型(prototype)中?

javascript - 如何在 onsubmit 事件中检查请求类型(ajax 或 no)?

javascript - 为什么动态值没有填充在自动完成组合框中?

javascript - 在 Backbone 模型中定义实例变量的正确方法是什么?

validation - 验证失败时,Backbone Validate 正在发送请求

javascript - Backbone.js:在集合中使用模型事件时不会触发

javascript - 如何验证动态创建的具有时间值的文本框

javascript - 如何在 JS 类中拥有 .on ('click' ) 事件

javascript - jquery 更改 span 标记的值 - 来自另一个 div 的引用