change event of model.save() firing twice in backbone

I've made view to listen to model changes. When there is change in model render function will be called and alert window will be prompted. But it is coming twice that means render function is calling twice because of two change events.

WineDetails View
app.WineView = Backbone.View.extend({

    template:_.template($('#tpl-wine-details').html()),

    initialize:function () {
        this.model.bind("change", this.render, this);

    },
    render:function (eventName) {
  if(eventName)alert("changed")
        $(this.el).html(this.template(this.model.toJSON()));
        return this;
    },

     events:{
        "change input":"change",
        "click .save":"saveWine",
        "click .delete":"deleteWine"
    },
    change:function (event) {
        var target = event.target;
        console.log('changing ' + target.id + ' from: ' + target.defaultValue + ' to: ' + target.value);
        // You could change your model on the spot, like this:
        // var change = {};
        // change[target.name] = target.value;
        // this.model.set(change);
    },
    saveWine:function () {
        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()) {
            var self = this;
         app.router.wineList.create(this.model,{wait:true,success:function(){
                 app.router.navigate('wines/'+self.model.id,false);
         }});//add event,request event on collection will be triggered

        } else {
            this.model.save();//change event,request event on model will be triggered
        }
        return false;
    },
onClose:function()
    {
        alert("onclose");
        this.model.unbind("change",this.render);
    }

And its not because of zombie view because i've this following code

Backbone.View.prototype.close=function()
{
    alert("closing view "+this);
    if(this.beforeClose){
        this.beforeClose();
    }
    this.remove();
    this.unbind();
    if(this.onClose){
        this.onClose();
    }

} 

please tell me what is wrong in this code. Thank u :)


So, as you didn't provide the information regarding your Model#save call, I'll assume it's the one within your view. I'll also assume the problem doesn't come from zombie views because you're following an outdated method for that. I'll make a guess here about what's probably happening:

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

Ok, the first part (the set method) will trigger a first change event.
The second part, the save method may trigger another change. Another set will indeed be done with the attributes sent back from the server.

Possible solution to a possible problem:
save can be passed attributes, and a wait flag to postpone the use of the set method until the server responds:

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

You can also try it by creating always a new instance of your model like :

var wine = new WineModel({
    name:$('#name').val(),
    grapes:$('#grapes').val(),
    country:$('#country').val(),
    region:$('#region').val(),
    year:$('#year').val(),
    description:$('#description').val()
});

And then save it like :

wine.save(null, success: function(model){
    // do your call action on call back
},
beforeSend: function() {
    // before save 
}
error: function(model, errors) {
    // on error occurred
});
链接地址: http://www.djcxy.com/p/63104.html

上一篇: 骨干事件被触发而没有触发

下一篇: 改变model.save()事件在主干中发射两次