简体   繁体   中英

Backbone.js: Rendering json data in a model

OK, super basic Backbone question - I've been searching all round for this, but am just too slow to get it despite a multitude of similar questions. Rest assured I am suitably ashamed.

Anyway, enough self-flagellation - why doesn't this render?

var app = app || {};

app.Option = Backbone.Model.extend({
url: 'http://localhost:4711/api'

//This url contains the following JSON: {"title": "Blahblah", "author": "Luke Skywalker"};  
});

 app.View = Backbone.View.extend({

el: 'body',

initialize: function(){
    this.model.fetch();
    this.model.bind('change', this.render(), this);
},

render: function(){
    this.$el.html(this.model.get('title'));
    return this;
}

});


$(function() {

 var option = new app.Option();
    this.homeView = new app.View({   //Tried changing this to a standard var declaration but didn't work
      model: option
    });
    this.homeView.render();
});

So I'm expecting to see the JSON "Blahblah" on the screen, but I see nothing. The JSON is being fetched correctly (I can see the successful GET request in the firebug console) and I think I've ensured the data is fetched before I attempt to render it...

So what's wrong? The console is giving me this error: "TypeError: (intermediate value).callback.call is not a function"

Thanks!

One thing is that you're calling this.render() immediately in your event binding rather than just binding the callback. Do this instead (using listenTo for best practices):

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

Is it possible that the model is not actually changing? You might try to bind to sync instead of change to see if that works.

You also render twice. Once directly with this.homeView.render() and once via the event handler. If you really want to keep your model fetch in initialize and bind to the change event you don't need the direct render.

Play with those and see if that doesn't fix it.

Just remove the parentheses from the render method while binding:

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

Also using on or listenTo is a better approach then bind .

I would construct the backbone skeleton in the following way:

var app = app || {};

app.Option.Model = Backbone.Model.extend({});

app.Option.Collection = Backbone.Collection.extend({       
   model : app.Option.Model,

   fetch : function(options) {     
       Backbone.Collection.prototype.fetch.call(this, options);
   },

   url : function() {
       return 'http://localhost:4711/api';
   },

   parse: function(response) { // this is the ajax call
      console.log(response);
   }
});

Then in View just call the fetch method on initialize:

app.Option.View = Backbone.View.extend({
    collection : app.Option.Collection,

    initialize : {
       this.collection.bind('reset', this.render, this); 
       this.collection.fetch();
    },

    render : {
       var results = this.collection.toJSON(); 
       console.log(results);
    }
});

This is my minimal backbone skeleton when i need to call a webservice. I haven't tested locally, but this way the code should work.

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