2017-06-21 63 views
-1

不知怎的,当我初始化我的看法,我得到一个错误Uncaught TypeError: Cannot read property 'toJSON' of undefinedBackbonejs - 我如何初始化视图?

我有以下代码:

//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}); 

不知怎的,当我初始化player查看playlist colleciton尚未填充呢。我可以从控制台运行var player = new Player({model: playlist})

+1

您很可能需要监听收集事件并渲染视图。如果你调试,什么变量是未定义的?另外,'playlist'是一个集合,所以它应该是'collection:playlist' – vassiliskrikonis

+0

这是this.model返回undefined – medicengonzo

+0

'model:playlist,'在视图属性中(在'extend'中)没用。这是一个应该在实例化时传递的选项,就像你在底部一样。 –

回答

1

你的收藏是空的。所以this.model.at(this.model.currentTrack);这实际上是this.collection.at(0);将返回undefined。因此你正在执行undefined.toJSON()

您需要在此处放置空检查并等待渲染前获取集合数据。

而且这是一个好主意,通过集合作为collection而不是model

+0

是的,它一开始是空的,但我用来自服务器的数据使用获取来填充它。应该在哪里调用获取方法? – medicengonzo

+0

或者我怎么能告诉currentSong()方法等待提取的数据? – medicengonzo

+0

@medicengonzo'this.fetch({success:function(){this.render();}})'或'this.fetch()。then(function(){this.render();})'或者你可以设置一个侦听器来“同步”事件,并将'render'设置为回调 –

0

我找到了答案!渲染之前,我必须等待集合中获取为T J said

他说,使用

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

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

但最终我

this.fetch().done(function(){ this.render() }); 
做到了