2017-06-21 3 views
-1

Irgendwie, wenn ich initialisieren meine Sicht Ich erhalte einen Fehler Uncaught TypeError: Cannot read property 'toJSON' of undefinedBackbonejs - Wie initialisiere ich die Ansicht?

Ich habe den folgenden Code:

//Model 
var Song = Backbone.Model.extend({ 
     defaults: { 
      title: 'Red', 
      artist: 'Taylor Swift', 
      filename: 'audio1.mp3', 
      playlist: 0 
     }, 

}); 

//Collection 
var Playlist = Backbone.Collection.extend({ 
    model: Song, 
    localStorage: new Backbone.LocalStorage('playlist'), 
    initialize: function(models,options) { 
     _.extend(this,_.pick(options, 'currentTrack')); 
     this.fetch({ajaxSync: true}) 
    }, 
    url: 'metadata', 
    parse: function(response){ 
     return response 
    }, 
    currentTrack: 0, 
    currentTime: 0 
}); 

//View 
var Player = Backbone.View.extend({ 
     tagName: "audio", 
     id: "player", 
     model: playlist, 
     currentSong: function(){ 
      console.log(this.model); 
      return this.model.at(this.model.currentTrack).toJSON(); 
     }, 
     events: { 
      'ended': 'next', 
      'pause': 'saveTime' 
     }, 
     newTemplate: _.template('<source src="<%= filename %>" >'), 
     initialize: function(){ 
      this.render(); 
     }, 
     render: function(){ 
      this.$el.html(this.newTemplate(this.currentSong())); 
      $(document.body).html(this.el); 
     }, 
     next: function(){ 
      if(this.model.length == this.model.currentTrack){ 
       console.log('End of the playlist'); 
      } 
      else{ 
      this.model.currentTrack++; 
      console.log('currentTrack: ', this.model.currentTrack); 
      this.render(); 
      this.el.src = this.currentSong().filename; 
      this.el.play(); 
      } 
     }, 
     saveTime: function(){ 
      console.log('Saving currentTime:', this.el.currentTime); 
      this.model.currentTime = this.el.currentTime; 
     } 
}); 


var playlist = new Playlist(); 
var player = new Player({model: playlist}); 

Irgendwie, wenn ich initialisieren die player sieht die playlist colleciton wurde noch nicht besiedelt. Ich kann var player = new Player({model: playlist}) in Ordnung von der Konsole laufen.

+1

Höchstwahrscheinlich müssen Sie auf Auflistungsereignisse warten und dann die Ansicht rendern. Wenn Sie debuggen, welche Variable ist nicht definiert? Außerdem ist 'playlist' eine Sammlung, also sollte es' collection: playlist' sein. – vassiliskrikonis

+0

Es ist dieses Modell, das undefined zurückgibt – medicengonzo

+0

'Modell: Playlist,' in den Ansichtseigenschaften (im 'extend') ist nutzlos. Dies ist eine Option, die an Instanziierung übergeben werden soll, wie Sie es am unteren Rand tun. –

Antwort

1

Ihre Sammlung ist leer. So this.model.at(this.model.currentTrack);, das ist eigentlich this.collection.at(0); wird undefined zurückgeben. Daher führen Sie undefined.toJSON() aus.

Sie müssen hier Null-Prüfungen setzen und darauf warten, dass die Sammlungsdaten vor dem Rendern abgerufen werden.

Und es ist eine gute Idee, die Sammlung als collection statt passieren model

+0

Ja, es ist zunächst leer, aber ich fülle es mit Daten vom Server mit Fetch. Wo soll die Fetch-Methode aufgerufen werden? – medicengonzo

+0

Oder wie kann ich die currentSong() Methode auf die abgerufenen Daten warten? – medicengonzo

+0

@medicengonzo 'this.fetch ({Erfolg: function() {this.render();}})' oder 'this.fetch(). Then (function() {this.render();})' oder Du kann einen Listener auf 'sync' Event einstellen und' render' als Callback zuweisen –

0

ich die Antwort gefunden! Vor dem Rendern muss ich warten, bis die Sammlung geholt werden als T J said

Er sagte

this.fetch({success: function(){ this.render }}) 

oder

this.fetch().then(function(){ this.render }); 

aber am Ende zu verwenden, ich habe es mit

this.fetch().done(function(){ this.render() }); 
Verwandte Themen