简体   繁体   中英

Uncaught TypeError: Cannot call method 'toJSON' of undefined in backbone

      var Person = Backbone.Model.extend({
    defaults: {
        name: "John Doe",
        age: 27,
        designation: "worker"
    },
    initialize : function(){
        this.on("invalid",function(model,error){
            alert(error);
        });
    },
    validate: function(attrs){
        if(attrs.age < 0){
         return 'Age must be positive,stupid';
        }
        if( ! attrs.name ){
            return 'Name should not be empty';
        }
    },

    work: function(){
        return this.get('name') + ' is a ' + this.get('designation');
    }
});

var PersonCollection = Backbone.Collection.extend({
    model: Person
});

var peopleView = Backbone.View.extend({
    tagName: 'ul',
    render: function(){
        //filter through all the items in a collections
        //for each, create a new PersonView
        //append it to root element

        this.collection.each(function(person){
            //console.log(person);
            var personView = new PersonView({model:person});
            this.$el.append(personView.render().el);
        },this);
    }
});

// The view for a Person
var PersonView = Backbone.View.extend({
    tagName : 'li',
    className : 'person',
    id : 'person-id',
    template: _.template( $('#personTemplate').html() ), 
    initialize : function(){
        _.bindAll(this,'render');
        //console.log(this.model)
        this.render();
    },

    render: function(){
        this.$el.html(this.template(this.model.toJSON()));
        return this;
    }
});

var modelperson = new Person;
var viewperson = new PersonView({model : modelperson});

var personCollection = new PersonCollection([
    {
        name: "raghu",
        age:24
    },
    {
        name: "shashank",
        age:23,
        designation: "CTO"
    },
    {
        name : "junaid",
        age : 30,
        designation : "UI"
    },
    {
        name: "vishnu",
        age: 23,
        designation: "content developer"
    }

    ]);

var peopleView = new PersonView({collection: personCollection});

I got the error like call to 'toJSON' undefined, I dont know how to get rid of this.

You need to pass model in your view

Change the last line of your code

var peopleView = new PersonView({collection: personCollection});

to

var peopleView = new PersonView({collection: personCollection,model:new Person()});

Demo

Updated, I think its peopleView instead of personView so the last line should be like,

 var pw = new peopleView ({collection: personCollection});
 pw.render();

then you need to change your peopleveiw like,

var peopleView = Backbone.View.extend({
    tagName: 'ul',
    render: function(){
        //filter through all the items in a collections
        //for each, create a new PersonView
        //append it to root element

        this.collection.each(function(person){
            //console.log(person);
            var personView = new PersonView({model:person});
            this.$el.append(personView.render().el);
        },this);
        // apend the element to body if not exists
        $(this.$el).appendTo('body');
    }
});

Updated Demo

Here is much cleaner code,which works at my end. Remember I'm using handlebars for templating, however the choice is your to use the templating library which you are comfortable with.

  var Person = Backbone.Model.extend({
      defaults: {
      name: "John Doe",
      age: 27,
      designation: "worker"
      },
      initialize : function(){
      this.on("invalid",function(model,error){
          alert(error);
      });
      },
      validate: function(attrs){
      if(attrs.age < 0){
       return 'Age must be positive,stupid';
      }
      if( ! attrs.name ){
          return 'Name should not be empty';
      }
      },
      work: function(){
      return this.get('name') + ' is a ' + this.get('designation');
      }
  });

  var PersonCollection = Backbone.Collection.extend({
      model: Person
  });

  var PersonView = Backbone.View.extend({
      el : "#list",
      render: function(){
      this.collection.each(function(person){
          var personViewItem = new PersonViewItem({model:person});
          this.$el.append(personViewItem.render().el);
      },this);
      }
  });

  // The view for a Person
  var PersonViewItem = Backbone.View.extend({
      tagName : 'li',
      className : 'person',
      template : Handlebars.compile($('#template').html()),
      initialize : function(){
         _.bindAll(this,'render');
         this.render();
      },
      render: function(){
          this.$el.html(this.template(this.model.toJSON()));
          return this;
      }
  });

  var personCollection = new PersonCollection([{name: "raghu",age:24},{name: "shashank",age:23,designation: "CTO"},{name : "junaid",age : 30,designation : "UI"},{name: "vishnu",age: 23,designation: "content developer"}]);     
  var peopleView = new PersonView({collection: personCollection});
  peopleView.render();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM