2012-06-16 20 views
0

我一直在試圖追蹤我的(相當簡單的)Backbone/Coffeescript代碼中的一個奇怪的錯誤。在主幹視圖上沒有「應用」方法

當運行我的應用程序,我得到這個錯誤:

Uncaught TypeError: Object #<IndexView> has no method 'apply' 

這裏是我的路由器:

class window.App.Router extends Backbone.Router 
    initialize: -> 
     Backbone.history.start({pushState: true}) 
     $(document).on "click", "a:not([data-bypass])", (evt) -> 
      href = $(this).attr "href" 
      protocol = this.protocol + "//" 
      if href.slice(protocol.length) != protocol 
       evt.preventDefault() 
       App.navigate(href, true) 

    routes: { 
     "": "index", 
     "artist/:id": "artist", 
     "albums/:id": "album" 
    } 

    index: 
     @view = new App.IndexView() 

和視圖:

class App.IndexView extends Backbone.View 
    template: "index" 
    el: $("#container") 

    initialize: -> 
     @render() 

    render: -> 
     get_template(@el, @template, @domEvents) 

    domEvents: -> 
     $("#searchInput").on "change keydown", -> 
      if $(this).val().length >= 0 
       $("#placeholder").css("display", "none") 
      else 
       $("#placeholder").css("display", "inline-block") 

從我的測試,似乎當我擺脫Backbone.history.start({pushState: true})代碼行時,此錯誤消失。不幸的是,我的應用程序需要pushState,所以消除這個不是一個選項。

有沒有人有什麼想法可能是錯誤的地方?

回答

2

你錯過了一個->當你在你的路由器定義index

class window.App.Router extends Backbone.Router 
    #... 
    index: 
     @view = new App.IndexView() 

結果是當你的App.Router類是正在建設和index成爲new App.IndexView()的值new App.IndexView()執行;另外,在這種情況下,@本身就是這個類,所以你最終設置了App.Router.view = new App.IndexView()。 JavaScript的看起來是這樣的:

Router.prototype.index = Router.view = new IndexView(); 

然後,因爲你的路線:

routes: { 
    "": "index", 
    #... 
} 

路由系統嘗試(使用Function.apply,以確保適當的調用上下文)來調用router.index的功能響應路由請求;但router.index是一個視圖實例,而不是一個函數/方法讓你得到你的錯誤:

Uncaught TypeError: Object #<IndexView> has no method 'apply' 

,因爲你不能叫上一個視圖實例apply

推測,您的Backbone.history.start({pushState: true})會觸發初始路由至index

因此,修復您的班級定義,將index定義爲一種方法,然後重試。


順便說一句,叫Backbone.history.start({pushState: true})內部路由器的initialize是有點匪夷所思。該usual process is to call startafter your routers have been created

When all of your Routers have been created, and all of the routes are set up properly, call Backbone.history.start() to begin monitoring hashchange events, and dispatching routes.

所以可能開始歷史上系統之前,所有的路由設置是否正確,並準備去。這可能會導致一些奇怪的事情發生。

+0

哇......這樣做...... *嘆息* 我也將Backbone.history.start()移動到新的Router()後面的一行。謝謝一堆! –