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

Posted

技术标签:

【中文标题】模型销毁的成功回调不起作用【英文标题】:Success Callback on Model destroy doesn't work 【发布时间】:2015-05-25 20:43:21 【问题描述】:

这是我的 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 行所见,“deletevine”功能被触发,尽管模型在服务器上被删除(200 响应),成功回调不会被触发!!

知道可能是什么问题吗?

【问题讨论】:

【参考方案1】:

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

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

你也可以告诉主干不要期望来自服务器的任何响应:

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。

【讨论】:

非常感谢@samad montazeri! .我看了一下那个问题,我根据@ccallendar 响应使用了model.destroy( dataType: "text", success: function(model, response) console.log("success"); ); ,它之所以有效,是因为我的服务器API 没有返回任何数据。 :D 顺便说一句,你知道为什么当我用第 232 行替换第 233 行时,代码会中断吗?我的意思是,我想要干净的 URL,我读过它只能通过使用 pushState,但它不起作用......我将非常感激 我对 Backbone js 了解不多。(而且我仍然不知道你的服务器端代码是什么!)。也许这可以帮助:backbone js routers confusion pushstate true trailing slash

以上是关于模型销毁的成功回调不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 5.0 路由模型绑定在销毁操作中不起作用

x-editable 的成功回调不起作用

FBSDKSharingDelegate 回调不起作用,即使发布工作正常

获取/发布回调中的NodeJS MQTT不起作用。

Cloudinary REST api 销毁不起作用? [关闭]

用于多输入模型的 R Keras predict_prob 不起作用。我可以成功地训练模型,但是在评分时出现错误