View + Sub Views in backbone/backbone

I've been learning a lot about backbone, backbone-relational and building web apps from reading through stackexchange - so first a thank you to the community.

Now, I am stuck at trying to understand this current issue involving nested models and sub views in what seems to me to be is a pretty common usecase.

I am trying to extend this tutorial to learn about backbone-relational, views/subviews and event handling by keepin track of "CheckIns" for each wine.

I have extended the server side to return appropriate JSON and backbone-relational model for checkIns like so:

window.CheckInModel = Backbone.RelationalModel.extend({
  defaults:{
        "_id":null,
        "Did":"true",
        "dateOf":"",
        }
});

window.CheckInCollection = Backbone.Collection.extend({
    model : CheckInModel
});

And the Wine Model like so:

relations: [{
 type: Backbone.HasMany, 
 key:'CheckIn',
 relatedModel: 'CheckInModel',
 collectionType: CheckInCollection,
     }] 

I've created a CheckInListView and CheckInItemView (same as WineListView and WineListItemView) and use the WineView Render function to render the CheckIns like so:

render:function (eventName) {
    console.log("wine View Render");
    $(this.el).html(this.template(this.model.toJSON()));

    this.myCheckInListView = new CheckInListView({model: this.model.attributes.CheckIn}); 
    this.$el.append(this.myCheckInListView.render().el);
    return this;
},

I've also created a new function within wineview that creates a checkin and associated with the given event:

logcheckin: function (event){
  var todate = new Date();
  newCheckIn = new CheckInModel ({'Did':"true", 'dateOf': todate.toISOString()});
  console.log ("Logcheckin - About to push newCheckIn onto Model.");
  this.model.attributes.CheckIn.push (newCheckIn); 
  console.log ("Just pushed newCheckIn onto Model.");
  this.saveWine();

}

Ok - if you haven't TL/DRed yet - This all seems to work fine from a UI perspective -ie. everything renders correctly and saves to the Db.

But I notice in the console that when I push a new CheckIn (between the console.logs above) the CheckInListView's Add binding gets called multiple times for wach button press - Which makes me think something is wrong with how I'm doing views or that I am not understanding something fundamental about event propagation.

Why is this happening ? Is it expected behavior ? Am I approaching what I am trying to do correctly ?

Thanks for reading if not your help.

==

Here are the relevant parts of the CheckinListView and CheckInList Item views that are bound to the add (and other) events.

window.CheckInListView = Backbone.View.extend({

        initialize:function () {
        this.model.bind("reset", this.render, this);
        this.model.bind("change", this.render, this);
        var self = this;
        this.model.bind("add", function (CheckIn) {
           console.log ("Adding to CheckInListView - a CheckIn List Item", CheckIn);
           self.$el.append(new CheckInListItemView({model:CheckIn}).render().el);
        });
    },  


       close:function () {
        $(this.el).unbind();
        $(this.el).remove();
    }
});

window.CheckInListItemView = Backbone.View.extend({

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

});

==============================================

The comment about event binding and closing views were the right hints for debugging this.

1) I was not closing and unbinding the nested views properly which left some ghost event consumers even though there was nothing in the DOM

2) You only need to bind events if we want to do something only in the subview.
For Example - If I have checkbox in a subview I can bind a subview change event in the main view and handle the event there since the mainview has model there anyway. I don't know if this is the "right" way but it works for what I need to do. (mm.. spaghetti code tastes so good)

3) Struggling with this helped me think through the UX some more and helped me simplify UI.

4) I was trying to "save" calls to the server by nesting all the data into on JSON call. And if I were to re-do this - I would not nest the data at all but handle it on the back end by associating the wine ID with checkIn ID and then having a separate collection that gets populated with the collection once a task is selected - I thought this would not be a the preferred way but it seems to be the way that a lot of people.

Still welcome any thoughts on the "right" way questions above or if anyone can point to a tutorial that goes beyond the "simple backbone app"


I'm not sure about everything that's happening, but, I've run into the problem of events firing multiple times before. If you're rendering multiple models using the same view, there's a chance that they're all being bound to the same event.

Perhaps this answer might apply: Cleaning views with backbone.js?

If not, you should respond to Edward M Smith's comment and show how your events are being bound.

链接地址: http://www.djcxy.com/p/65524.html

上一篇: 服务器响应之前的关系触发添加事件

下一篇: 查看主干/骨干中的+子视图