Backbone.Collection.Create not triggering “add” in

2020-04-18 04:05发布

问题:

Hopefully this is an easy question. I'm trying to learn backbone and i'm stuck on a really simple thing. the render on the view never gets called when I update the collection by using the create method. I thought this should happen without explicitly calling render. I'm not loading anything dynamic, it's all in the dom before this script fires. The click event works just fine and I can add new models to the collection, but the render in the view never fires.

$(function(){

window.QuizMe = {};

// create a model for our quizzes
QuizMe.Quiz = Backbone.Model.extend({
// override post for now
"sync": function (){return true},

});

QuizMe._QuizCollection = Backbone.Collection.extend({
model: QuizMe.Quiz,
});

QuizMe.QuizCollection = new QuizMe._QuizCollection

QuizMe.QuizView = Backbone.View.extend({

el:$('#QuizMeApp'),

template: _.template($('#quizList').html()),

events: {
  "click #addQuiz" : "addQuizDialog",
},

initialize: function() {
// is this right?
  _.bindAll(this,"render","addQuizDialog")
  this.model.bind('add', this.render, this);

},

addQuizDialog: function(event){
  console.log('addQuizDialog called')
  QuizMe.QuizCollection.create({display:"this is a display2",description:"this is a succinct description"});  
},

render: function() {
  console.log("render called")
},
});

QuizMe.App = new QuizMe.QuizView({model:QuizMe.Quiz})

});

回答1:

Your problem is that you're binding to the model:

this.model.bind('add', this.render, this);

but you're adding to a collection:

QuizMe.QuizCollection.create({
    display:     "this is a display2",
    description: "this is a succinct description"
});

A view will usually have an associated collection or model but not both. If you want your QuizView to list the known quizzes then:

  1. You should probably call it QuizListView or something similar.
  2. Create a new QuizView that displays a single quiz; this view would have a model.
  3. Rework your QuizListView to work with a collection.

You should end up with something like this:

QuizMe.QuizListView = Backbone.View.extend({
    // ...
    initialize: function() {
        // You don't need to bind event handlers anymore, newer
        // Backbones use the right context by themselves.
        _.bindAll(this, 'render');
        this.collection.bind('add', this.render);
    },
    addQuizDialog: function(event) {
        this.collection.create({
            display:     "this is a display2",
            description: "this is a succinct description"
        });
    },
    render: function() {
        console.log("render called")
        // And some stuff in here to add QuizView instances to this.$el
        return this; // Your render() should always do this.
    }
});

QuizMe.App = new QuizMe.QuizView({ collection: QuizMe.QuizCollection });

And watch that trailing comma after render, older IEs get upset about that and cause difficult to trace bugs.

I'd give you a quick demo but http://jsfiddle.net/ is down at the moment. When it comes back, you can start with http://jsfiddle.net/ambiguous/RRXnK/ to play around, that fiddle has all the appropriate Backbone stuff (jQuery, Backbone, and Underscore) already set up.



标签: backbone.js