2014-07-20 122 views
0

我一直從我的模型調用的事件得到以下錯誤:骨幹觸發()返回類型錯誤

window.Playlist = new PlaylistModel(); 
Playlist.trigger("playerPlaying"); 
`Uncaught TypeError: Cannot read property '0' of undefined` 

我的堆棧跟蹤:

Uncaught TypeError: Cannot read property '0' of undefined 
triggerEventsbackbone.js:206 
Backbone.Events.triggerbackbone.js:148 
onPlayerStateChangeplayer.js:101 
g.Iwww-widgetapi-vfldqBTcy.js:13 
g.kwww-widgetapi-vfldqBTcy.js:22 
g.Jwww-widgetapi-vfldqBTcy.js:30 
X.dwww-widgetapi-vfldqBTcy.js:29 
Qa.fwww-widgetapi-vfldqBTcy.js:18 

我挖骨幹源代碼並找到如下

trigger: function(name) { 
    if (!this._events) return this; 
    var args = slice.call(arguments, 1); 
    if (!eventsApi(this, 'trigger', name, args)) return this; 
    var events = this._events[name]; 
    var allEvents = this._events.all; 
    if (events) triggerEvents(events, args); 
    if (allEvents) triggerEvents(allEvents, arguments); 
    return this; 

從chrome控制檯設置斷點後,我逐行打印了這些行。

arguments = ["playerPlaying"] 
args = [] 
this._events = Object {change:currentSong: Array[3], change:loopActive: Array[3], playerPlaying: Array[3]} 
events = [Object, Object, Object] 
this = the Backbone model on which `trigger()` was called 

我認爲這個問題是arguments應該是[ModelThatTriggeredEvent,eventName的]但我只得到[eventName的]所以args變成空數組。有誰知道爲什麼會發生這種情況?

更新:

這裏就是整個PlaylistModel與刪除了一些零件。請理解代碼中的混亂情況,因爲我正在重構它以遵守Backbone的做事方式。

define([ 
    // These are path alias that we configured in our bootstrap 
    'jquery',  // lib/jquery/jquery 
    'backbone', 
    '../../common/models/song', 
    '../collections/songs' 
], function($, Backbone, Song, Songs){ 

    window.AVAILABLE_CHARTS = { 
    billboardChart: { 
     source: "billboard", 
     chart: [ 
     {genre: chrome.i18n.getMessage("pop"), url: 'http://www.billboard.com/rss/charts/hot-100'}, 
     {genre: chrome.i18n.getMessage("rock"), url: "http://www.billboard.com/rss/charts/rock-songs"}, 
     ] 
    } 
    }; 

    var Playlist = Backbone.Model.extend({ 
    defaults: { 
     currentSong: null, 
     nextSong: null, 
     prevSong: null, 
     genre: null, // initial genre 
     loopActive: false, 
     shuffleActive: false, 
     numSongs: 10, // initial number of songs loaded 
     musicChart: null 
    }, 

    initialize: function() { 
     // Setting collections/songs as its attribute 
     var songs = new Songs(); 
     this.set('songs', songs); 

     var userLocale = chrome.i18n.getMessage("@@ui_locale"); 
     if (userLocale == "ko" || userLocale == 'ko-kr') { 
     this.set('musicChart', AVAILABLE_CHARTS.melonChart); 
     this.set('genre', this.get('musicChart').chart[0].genre); 
     } else { 
     this.set('musicChart', AVAILABLE_CHARTS.billboardChart); 
     this.set('genre', this.get('musicChart').chart[0].genre); 
     } 
    }, 

    // If loop is active, getNextSong repeats the current song 
    // If shuffle is active, getNextSong plays a random song from Songs 
    getNextSong: function() { 
     //var idx = this.indexOf(this.getCurrentSong()); 
     var songs = this.get('songs'); 
     var idx = songs.indexOf(songs.findWhere({ title: this.get('currentSong').get('title') })); 
     if (this.get('loopActive')) { 
     return songs.at(idx); 
     } 
     if (this.get('shuffleActive')) { 
     var randomIndex = Math.floor((Math.random()*songs.length)); 
     return songs.at(randomIndex); 
     } 
     if (idx != songs.length-1) return songs.at(idx+1); 
     else return songs.at(0); 
    }, 

    getPrevSong: function() { 
     var songs = this.get('songs'); 
     var idx = songs.indexOf(songs.findWhere({ title: this.get('currentSong').get('title') })); 
     if (idx != 0) return songs.at(idx-1); 
     else return songs.at(songs.length-1); 
    }, 

    // Get new songs from Billboard Chart 
    // First parse the top <numSongs> from the selected <genre> 
    // from Billboard, and then use YouTube gdata api to fetch 
    // the songs. 
    getNewSongs: function (callback, genre, numSongs) { 
     // FIXME: just trigger progress 
     var popupWindow = chrome.extension.getViews({ type: "popup" })[0]; 
     if (popupWindow && popupWindow.popupView) popupWindow.popupView.setProgress(10); 
     var playlist = this; 
     playlist.get('songs').reset(); 
     // Inspect Billboard Chart to find pop songs 
     $.get(url+numSongs+'/explicit=true/xml', function (data) { 
      var popupWindow = chrome.extension.getViews({ type: "popup" })[0]; 
      if (popupWindow && popupWindow.popupView) popupWindow.popupView.setProgress(30); 
      var $feed = $(data).find('feed') 
      var $entries = $feed.find('entry') 
      var numAvailableSongs = $entries.length; 
      $entries.each(function (idx, entry) { 
      var title_artist_pair = $(entry).find('title')[0].innerHTML; 
      var title = $.trim(title_artist_pair.split(' - ')[0]); 
      var artist = $.trim(title_artist_pair.split(' - ')[1]); 
      var rank = idx+1; 
      var query = title + " " + artist; 
      _searchYouTube(title, artist, rank, query, numAvailableSongs); 
      }); 
      return; 
     }); 
    } 

     function _searchYouTube (title, artist, rank, query, numAvailableSongs) { 
     var songs = playlist.get('songs'); 

     $.ajax({ 
      url: searchUrl, 
      type: "GET", 
      data: 'q='+encodeURIComponent(query), 
      success: function (result) { 
      //console.log("\n**** 검색: "+query); 
      ajaxCount += 1; 

      if (result.items.length) 
       var videoId = result.items[0].id.videoId; 
      else 
       var videoId = null; // Cannot find the song on YouTube 

      var song = new Song({ 
       title: title, 
       artist: artist, 
       rank: parseInt(rank), 
       query: query, 
       videoId: videoId 
      }); 

      // Insert songs into the playlist in the order of their ranks 
      // *Note: Songs that do not exist on YouTube are ignored 
      if (videoId) songs.add(song, { silent: true }); 

      // All the ajax calls are finished 
      if (ajaxCount == numAvailableSongs) { 
       var popupWindow = chrome.extension.getViews({ type: "popup" })[0]; 
       if (popupWindow && popupWindow.popupView) popupWindow.popupView.setProgress(70); 
       songs.comparator = 'rank' 
       songs.sort(); 
       // Remove useless playlsit methods 
       if (!playlist.get('currentSong')) { 
       playlist.set('currentSong', songs.at(0)); 
       } 
       callback(); 
      } 
      }, 
      error: function (error) { 
      ajaxCount += 1; 
      if (ajaxCount == numAvailableSongs) { 
       var popupWindow = chrome.extension.getViews({ type: "popup" })[0]; 
       if (popupWindow) popupWindow.popupView.setProgress(70); 
       if (!playlist.get('currentSong')) { 
       playlist.set('currentSong', songs.at(0)); 
       } 
       callback(); 
      } 
      } // end of error 
     }); // end of second ajax 
     } // end of _searchYouTube() 
    }, 

    lookUpAndAddSingleSong: function (query) { 
     var playlist = this; 
     var youtubeAPIKey = "fdf"; 
     var initialSearchURL = "df"; 
     var searchUrl = initialSearchURL + "&key=" + youtubeAPIKey; 
     $.ajax({ 
     url: searchUrl, 
     type: "GET", 
     data: 'q='+encodeURIComponent(query), 
     success: function (result) { 
      if (result.items.length) { 
      var videoId = result.items[0].id.videoId; 
      var song = new Song({ 
       title: result.items[0].snippet.title, 
       query: query, 
       videoId: videoId 
      }); 
      } else var videoId = null; // Cannot find the song on YouTube 

      if (videoId) { 
      playlist.get('songs').add(song); 
      song.save(); // save to localStorage 
      } 
     }, error: function (xhr, status, errorThrown) { 
      var errorMessage = "lookUpAndAddSingleSong error: check http://instantmusicapp.com"; 
      var popupWindow = chrome.extension.getViews({ type: "popup" })[0]; 
      if (popupWindow && popupWindow.popupView) popupWindow.showErrorMessage(errorMessage); 
      return; 
     } 
     }); 
    }, 

    setMusicChart: function (chartName) { 
     // if the chart is provided, we pick from Melon, Billboard, iTunes 
     if (chartName) { 
     if (chartName == chrome.i18n.getMessage("melonChart")) 
      this.set('musicChart', AVAILABLE_CHARTS.melonChart); 
     else if (chartName == chrome.i18n.getMessage("billboardChart")) 
      this.set('musicChart', AVAILABLE_CHARTS.billboardChart); 
     else 
      this.set('musicChart', AVAILABLE_CHARTS.itunesChart); 
     // else, the user is looking for a personal favorite chart 
     } else { 
     this.set('musicChart', AVAILABLE_CHARTS.myChart); 
     } 
    }, 
    }); 

    return Playlist; 
}); 
+0

我開始尋找更進一步,你的'PlaylistModel'代碼是什麼樣子? – christian314159

+0

現在在外面,但我會很快在這裏發佈。你有沒有想過爲什麼會發生這種情況,而不看代碼? –

+0

這些在實例化和觸發代碼中沒有任何問題,在'PlayListModel'代碼 –

回答

0

有相當模型中的一些語法錯誤,這可能是爲什麼你正在從你的BB模型發出觸發和甚至其他任何東西阻止的。

第14行有一個懸空逗號(,)。

嘗試通過JSLint或JSHint運行您的模型並修復錯誤。可能會解決您的問題

0

懸掛逗號在大多數瀏覽器中都可以接受,但實際錯誤是getNewSongs函數之後的額外}。我建議使用一些支持JSHint集成的IDE /編輯器。你可以嘗試webstorm。這是更新的代碼。

define([ 
    // These are path alias that we configured in our bootstrap 
    'jquery',  // lib/jquery/jquery 
    'backbone', 
    '../../common/models/song', 
    '../collections/songs' 
], function ($, Backbone, Song, Songs) { 

    window.AVAILABLE_CHARTS = { 
     billboardChart: { 
      source: "billboard", 
      chart: [ 
       {genre: chrome.i18n.getMessage("pop"), url: 'http://www.billboard.com/rss/charts/hot-100'}, 
       {genre: chrome.i18n.getMessage("rock"), url: "http://www.billboard.com/rss/charts/rock-songs"}, 
      ] 
     } 
    }; 

    var Playlist = Backbone.Model.extend({ 
     defaults: { 
      currentSong: null, 
      nextSong: null, 
      prevSong: null, 
      genre: null, // initial genre 
      loopActive: false, 
      shuffleActive: false, 
      numSongs: 10, // initial number of songs loaded 
      musicChart: null 
     }, 

     initialize: function() { 
      // Setting collections/songs as its attribute 
      var songs = new Songs(); 
      this.set('songs', songs); 

      var userLocale = chrome.i18n.getMessage("@@ui_locale"); 
      if (userLocale == "ko" || userLocale == 'ko-kr') { 
       this.set('musicChart', AVAILABLE_CHARTS.melonChart); 
       this.set('genre', this.get('musicChart').chart[0].genre); 
      } else { 
       this.set('musicChart', AVAILABLE_CHARTS.billboardChart); 
       this.set('genre', this.get('musicChart').chart[0].genre); 
      } 
     }, 

     // If loop is active, getNextSong repeats the current song 
     // If shuffle is active, getNextSong plays a random song from Songs 
     getNextSong: function() { 
      //var idx = this.indexOf(this.getCurrentSong()); 
      var songs = this.get('songs'); 
      var idx = songs.indexOf(songs.findWhere({ title: this.get('currentSong').get('title') })); 
      if (this.get('loopActive')) { 
       return songs.at(idx); 
      } 
      if (this.get('shuffleActive')) { 
       var randomIndex = Math.floor((Math.random() * songs.length)); 
       return songs.at(randomIndex); 
      } 
      if (idx != songs.length - 1) return songs.at(idx + 1); 
      else return songs.at(0); 
     }, 

     getPrevSong: function() { 
      var songs = this.get('songs'); 
      var idx = songs.indexOf(songs.findWhere({ title: this.get('currentSong').get('title') })); 
      if (idx != 0) return songs.at(idx - 1); 
      else return songs.at(songs.length - 1); 
     }, 

     // Get new songs from Billboard Chart 
     // First parse the top <numSongs> from the selected <genre> 
     // from Billboard, and then use YouTube gdata api to fetch 
     // the songs. 
     getNewSongs: function (callback, genre, numSongs) { 
      // FIXME: just trigger progress 
      var popupWindow = chrome.extension.getViews({ type: "popup" })[0]; 
      if (popupWindow && popupWindow.popupView) popupWindow.popupView.setProgress(10); 
      var playlist = this; 
      playlist.get('songs').reset(); 
      // Inspect Billboard Chart to find pop songs 
      $.get(url + numSongs + '/explicit=true/xml', function (data) { 
       var popupWindow = chrome.extension.getViews({ type: "popup" })[0]; 
       if (popupWindow && popupWindow.popupView) popupWindow.popupView.setProgress(30); 
       var $feed = $(data).find('feed') 
       var $entries = $feed.find('entry') 
       var numAvailableSongs = $entries.length; 
       $entries.each(function (idx, entry) { 
        var title_artist_pair = $(entry).find('title')[0].innerHTML; 
        var title = $.trim(title_artist_pair.split(' - ')[0]); 
        var artist = $.trim(title_artist_pair.split(' - ')[1]); 
        var rank = idx + 1; 
        var query = title + " " + artist; 
        _searchYouTube(title, artist, rank, query, numAvailableSongs); 
       }); 
       return; 
      }); 


      function _searchYouTube(title, artist, rank, query, numAvailableSongs) { 
       var songs = playlist.get('songs'); 

       $.ajax({ 
        url: searchUrl, 
        type: "GET", 
        data: 'q=' + encodeURIComponent(query), 
        success: function (result) { 
         //console.log("\n**** 검색: "+query); 
         ajaxCount += 1; 

         if (result.items.length) 
          var videoId = result.items[0].id.videoId; 
         else 
          var videoId = null; // Cannot find the song on YouTube 

         var song = new Song({ 
          title: title, 
          artist: artist, 
          rank: parseInt(rank), 
          query: query, 
          videoId: videoId 
         }); 

         // Insert songs into the playlist in the order of their ranks 
         // *Note: Songs that do not exist on YouTube are ignored 
         if (videoId) songs.add(song, { silent: true }); 

         // All the ajax calls are finished 
         if (ajaxCount == numAvailableSongs) { 
          var popupWindow = chrome.extension.getViews({ type: "popup" })[0]; 
          if (popupWindow && popupWindow.popupView) popupWindow.popupView.setProgress(70); 
          songs.comparator = 'rank' 
          songs.sort(); 
          // Remove useless playlsit methods 
          if (!playlist.get('currentSong')) { 
           playlist.set('currentSong', songs.at(0)); 
          } 
          callback(); 
         } 
        }, 
        error: function (error) { 
         ajaxCount += 1; 
         if (ajaxCount == numAvailableSongs) { 
          var popupWindow = chrome.extension.getViews({ type: "popup" })[0]; 
          if (popupWindow) popupWindow.popupView.setProgress(70); 
          if (!playlist.get('currentSong')) { 
           playlist.set('currentSong', songs.at(0)); 
          } 
          callback(); 
         } 
        } // end of error 
       }); // end of second ajax 
      } // end of _searchYouTube() 
     }, 

     lookUpAndAddSingleSong: function (query) { 
      var playlist = this; 
      var youtubeAPIKey = "fdf"; 
      var initialSearchURL = "df"; 
      var searchUrl = initialSearchURL + "&key=" + youtubeAPIKey; 
      $.ajax({ 
       url: searchUrl, 
       type: "GET", 
       data: 'q=' + encodeURIComponent(query), 
       success: function (result) { 
        if (result.items.length) { 
         var videoId = result.items[0].id.videoId; 
         var song = new Song({ 
          title: result.items[0].snippet.title, 
          query: query, 
          videoId: videoId 
         }); 
        } else var videoId = null; // Cannot find the song on YouTube 

        if (videoId) { 
         playlist.get('songs').add(song); 
         song.save(); // save to localStorage 
        } 
       }, error: function (xhr, status, errorThrown) { 
        var errorMessage = "lookUpAndAddSingleSong error: check http://instantmusicapp.com"; 
        var popupWindow = chrome.extension.getViews({ type: "popup" })[0]; 
        if (popupWindow && popupWindow.popupView) popupWindow.showErrorMessage(errorMessage); 
        return; 
       } 
      }); 
     }, 

     setMusicChart: function (chartName) { 
      // if the chart is provided, we pick from Melon, Billboard, iTunes 
      if (chartName) { 
       if (chartName == chrome.i18n.getMessage("melonChart")) 
        this.set('musicChart', AVAILABLE_CHARTS.melonChart); 
       else if (chartName == chrome.i18n.getMessage("billboardChart")) 
        this.set('musicChart', AVAILABLE_CHARTS.billboardChart); 
       else 
        this.set('musicChart', AVAILABLE_CHARTS.itunesChart); 
       // else, the user is looking for a personal favorite chart 
      } else { 
       this.set('musicChart', AVAILABLE_CHARTS.myChart); 
      } 
     } 
    }); 

    return Playlist; 
}); 
+0

謝謝你們兩位!讓我驗證這是否有效。 –

+0

不幸的是,在分解整個代碼之後,問題仍然存在。 –

+0

你可以再次發佈整個代碼嗎? –