【问题标题】:backbone model saving and callback issues主干模型保存和回调问题
【发布时间】:2026-01-17 13:35:01
【问题描述】:

我刚开始使用 Backbone。根据下面的代码,我有两个问题要问。

第一个问题是在我填写表格并单击按钮后,应该使用一些默认属性创建模型对象。但是,console.log 会在我将模型传递给新视图对象之前使用我填写的表单中的最新属性打印模型。

第二个问题是我可以成功将数据保存到db,但是我的成功回调函数没有被调用。有人可以帮我回答这些问题吗?

var form = document.forms[0];

var RetailerModel = Backbone.Model.extend({
    urlRoot: ' retailer.php',
    defaults: {
        name: 'company-name',
        address: 'company-address',
        phone: 'company-phone',
        icon: 'http://localhost/icon.png'
    }
});

var RetailerCollection = Backbone.Collection.extend({

});

var RetailerView = Backbone.View.extend({

    className: 'retailer',

    template: _.template($('#retailer-template').html()),

    initialize: function() {
        //this.listenTo(this.model, 'change', this.render);

        var obj = {
            name: form.name.value,
            address: form.address.value,
            phone: form.phone.value
        };

        this.model.set(obj);
        //why the successful callback does not work????
        this.model.save(null, {success: function(model, response){console.log('successful');}});
    },

    render: function() {
        $('#retailer-list').append(this.$el.html(this.template(this.model.toJSON())));

        return this;
    }
});

var RetailerViews = Backbone.View.extend({

});

$('#submit').click(function(e){
    var retailer_model = new RetailerModel();
    console.log(retailer_model); // this prints out the new changed attributes instead of the default ones, why???
    var retailer_view = new RetailerView({model: retailer_model});
    form.reset();
});

【问题讨论】:

    标签: javascript backbone.js callback backbone-model


    【解决方案1】:

    1 获取模型的正确状态

    console.log(retailer_model) 不会显示模型属性,它会显示整个模型,但console.log(retailer_model.attributes) 会。还要记住console.log 并不总是正确,尤其是如果您在记录后修改对象,这可能会导致混乱!

    要获得模型的实际当前状态,您应该对其进行浅拷贝或深拷贝。因此,您可以使用underscores clone 方法而不是console.log(model) 进行浅拷贝:

    console.log(_(model).clone());

    2 保存成功回调

    为了提供帮助,我们确实需要更多地了解您的情况。我要寻找的第一件事是您的服务器是否正在返回正确的反馈。 Backbone 是一个基于 REST 标准的系统。您确定您的服务器正在返回正确的响应代码吗?如果您使用 chrome,请打开您的开发人员工具,然后打开网络选项卡以检查您在发布模型时得到的响应。为了触发成功回调,服务器应返回 200 或 201 的状态。

    另一种测试方法是查看错误回调是否正在触发:)。

    【讨论】:

    • 请告诉我你的服务器返回了什么HTTP状态,我想知道到底是什么问题。
    【解决方案2】:

    我试图查看您的错误,我意识到您错过了这些事情:
    1。当 DOM 就绪事件触发时,你应该做 DOM 相关的事情:

    $(function() { 
        form = document.forms[0];
        $(form).live('submit', function(e){
            // ...
        });
    });
    


    2.您可以将submit 用于表单。它还捕获enter 在表单内单击:

    $(form).live('submit',function(){
        //...
    });
    


    3.您应该在提交表单中使用return false;。它可以防止默认表单数据发送到操作 url。

    $(form).live('submit', function(e){
        // ...
        return false;
    });
    

    所以,它看起来像这样。我没有检查成功回调,但我希望它会起作用。

    <html>
    <head>
    <script src="jquery-1.7.2.js" type="text/javascript"></script>
    <script type="text/javascript" src="underscore.js"></script>
    <script type="text/javascript" src="backbone.js"></script>
    <script type="text/javascript">
    
    var RetailerModel = Backbone.Model.extend({
        urlRoot: ' retailer.php',
        defaults: {
            name: 'company-name',
            address: 'company-address',
            phone: 'company-phone',
            icon: 'http://localhost/icon.png'
        }
    });
    
    var RetailerCollection = Backbone.Collection.extend({});
    
    var RetailerView = Backbone.View.extend({
    
        className: 'retailer',
    
        //template: _.template($('#retailer-template').html()),
    
        initialize: function() {
            //this.listenTo(this.model, 'change', this.render);
    
            var obj = {
                name: form.name.value,
                address: form.address.value,
                phone: form.phone.value
            };
    
            this.model.set(obj);
            //why the successful callback does not work????
            this.model.save(null, {
                success: function(model, response){
                    console.log('successful');
                }
            });
        },
    
        render: function() {
            $('#retailer-list').append(this.$el.html(this.template(this.model.toJSON())));
            return this;
        }
    });
    
    var RetailerViews = Backbone.View.extend({});
    $(function() { // you should do DOM related things when DOM ready event fired
        form = document.forms[0];
        $(form).live('submit', function(e){
            var retailer_model = new RetailerModel();
            console.log(retailer_model);
            var retailer_view = new RetailerView({model: retailer_model});
            form.reset();
    
            return false; // to prevent form data sending return false
        });
    });
    </script>
    
    </head>
    <body>
        <form action="#" id="#submit">
            <input type="submit" value="submit"/>
            <input type="text" name="address"/>
            <input type="text" name="name"/>
            <input type="text" name="phone"/>
        </form>
    </body>
    </html>
    

    【讨论】: