Backbone.js: rendering json data in a model

OK, a super basic layout question - I searched all around, but too slowly to get it, despite a lot of similar questions. Be sure I'm ashamed.

In any case, self-flagellation is enough - why doesn't it?

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 expect to see JSON "Blahblah" on the screen, but I do not see anything. JSON is correctly selected (I see a successful GET request in the firebug console), and I think I made sure that the data is retrieved before I try to execute it ...

So what happened? The console gives me this error: "TypeError: (intermediate value) .callback.call is not a function"

Thanks!

+4
source share
3 answers

It is one thing that you call this.render() immediately in the event binding, and not just bind 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 does not actually change? You can try to bind to sync instead of change to see if this works.

You also render twice. Directly using this.homeView.render() and once through the event handler. If you really want to save the model selection in initialize and bind to the change event, you do not need direct rendering.

Play with them and see if this fixes.

+5
source

Just remove the parentheses from the rendering method when binding:

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

Also using on or listenTo better than bind .

+4
source

I would build the skeleton of the base as follows:

 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 the view, just call the fetch method on initialization:

 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 spine skeleton when I need to call a web service. I have not tested locally, but this way the code should work.

+1
source

Source: https://habr.com/ru/post/1502112/


All Articles