简体   繁体   中英

Backbone.js fetch() JSON to model get() returns undefined

Basically I want to fetch a JSON file and store it in a model. However, when I try to access the attributes via get() it returns undefined. So lets say the JSON file has an array games that consists of objects with some attributes. It doesn't really matter. Just want to save them in the model and access them. So I'm doing something like this.

var player = Backbone.Model.extend({
   initialize: function(app, options) {
      this.app = app;
      var _this = this;

      this.fetch({
         url: "someurl",
         success: function() {
            console.log("success");
         }
      });
   }
});

var instplayer = new player();
instplayer.on('change', function(){
   console.log(model);
   console.log(model.get(games));
})

So I figured that I need an event to ensure that get() is called when the data is really available. But this still returns undefined. What do I need to do?

So I imagined you have a json for your player like this (I've mocked it here for the example below to work):

{
    "username": "joe",
    "games": [
        {
            "title": "Pacman"
        }, {
            "title": "Super Mario" } 
    ]
}

And here's a complete working example of how I would deal with managing and rendering this kind of data:

 var Game = Backbone.Model.extend({ defaults: { title: '' } }); var Games = Backbone.Collection.extend({ model: Game }); var Player = Backbone.Model.extend({ defaults: { username: '' }, url: 'http://www.mocky.io/v2/56261127250000a01accb34f', initialize: function(){ this.games = new Games(); this.listenTo( this, "sync", this.initGames ); this.fetch(); }, initGames: function(){ this.games.add( this.get('games') ); this.trigger('ready', this); } }); var PlayerView = Backbone.View.extend({ template: _.template('<h1><%=username%></h1> and his games: <ol class="games"></ol>'), render: function(){ this.$el.html( this.template( this.model.toJSON() ) ); this.model.games.each( this.renderGame, this ); return this; }, renderGame: function(game, i){ var gameView = new GameView({ model: game }); gameView.render().$el.appendTo( this.$('.games') ); } }); var GameView = Backbone.View.extend({ tagName: 'li', template: _.template('<strong>Game:</strong> <%=title%>'), render: function(){ this.$el.html( this.template( this.model.toJSON() )); return this; } }); var dude = new Player(); dude.on('ready', function(player){ var playerView = new PlayerView({ model: player }); playerView.render().$el.appendTo( document.body ); }); 
 <script src='http://code.jquery.com/jquery.js'></script> <script src='http://underscorejs.org/underscore.js'></script> <script src='http://backbonejs.org/backbone.js'></script> 

I don't know if it's a typo or not but you are not passing model to the callback

instplayer.on('change', function(){
  console.log(model);
  console.log(model.get(games));
})

it should be

instplayer.on('change', function(model, options){
  console.log(model);
  console.log(model.get("games"));
})

then games must be a string not a variable .

Another thing I suggest you to be aware of is what the json returns; sometimes you have to override the parse function to get the exact results.

Again if your fetching an array and not a single object, maybe you should use a collection of players

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