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,所以摆脱它不是一种选择。

有没有人知道这里可能出了什么问题?

4

1 回答 1

2

当您在路由器中->定义时,您错过了:index

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

结果是new App.IndexView()在您的App.Router类正在构建时执行并index成为new App.IndexView(); 此外,在这种情况下@是类本身,所以你最终设置App.Router.view = new App.IndexView(). JavaScript 看起来像这样:

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

然后,由于您的路线:

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

路由系统尝试router.index作为函数调用(Function.apply用于确保适当的调用上下文)以响应路由请求;但是router.index是一个视图实例而不是一个函数/方法,所以你得到你的错误:

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

因为你不能调用apply视图实例。

据推测,您Backbone.history.start({pushState: true})触发了初始路由到index.

因此,修复您的类定义以定义index为方法,然后重试。


Backbone.history.start({pushState: true})顺便说一句,在路由器内部打电话initialize有点奇怪。通常的过程是在您的路由器创建start 调用:

当您的所有路由器都已创建,并且所有路由都已正确设置后,调用Backbone.history.start()以开始监视hashchange事件和调度路由。

因此,可能会在所有路由都正确设置并准备就绪之前启动历史系统。这可能会导致一些奇怪的事情发生。

于 2012-06-16T19:52:17.447 回答