我一直试图在我的(相当简单的)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,所以摆脱这个不是一个选项。
有没有人对这里的错误有任何想法?
答案 0 :(得分: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
有点奇怪。 usual process is to call start
after your routers have been created:
如果已创建所有路由器并且所有路由都已正确设置,请致电
Backbone.history.start()
以开始监控hashchange
个事件并调度路径。
因此可能在所有路由正确设置并准备好之前启动历史记录系统。这可能会导致一些奇怪的事情发生。