我有一个Backbone Marionette应用程序,下面定义了一个模块。当我运行此应用程序时,控制台日志语句打印出@
作为窗口对象。运行list
方法时,我认为this
(@
)会引用List.Controller
对象。我错过了什么?
###
The Header list controller.
###
define [
'cs!app',
'cs!./view',
'cs!modules/header/entities'
], (
App,
View
) ->
App.module 'Header.List', (List, App, Backbone, Marionette, $, _) ->
List.Controller =
list: ->
console.log(@)
headers = App.request 'header:entities'
view = new View.Headers {collection: headers}
App.headerRegion.show view
setActiveHeader: (headerUrl) ->
headers = App.request 'header:entities'
header = headers.find (header) -> (header.get 'url') == headerUrl
header.select()
headers.trigger 'reset'
App.commands.setHandler 'header:setActive', (headerUrl) ->
List.Controller.setActiveHeader headerUrl
App.Header.List.Controller
更新
这是调用list方法的模块:
###
The Header module.
###
define [
'cs!app',
'cs!./list/controller'
], (
App,
listController
) ->
App.module 'Header', (Module, App, Backbone, Marionette, $, _) ->
Module.startWithParent = false
App.module 'Routers.Header', (ModuleRouter, App, Backbone, Marionette, $, _) ->
class ModuleRouter.Router extends Marionette.AppRouter
appRoutes: {}
executeAction = (action, args) ->
action(args)
API =
list: ->
executeAction listController.list
App.Header.on 'start', ->
API.list()
App.addInitializer ->
new ModuleRouter.Router {listController: API}
App.Header
答案 0 :(得分:2)
问题是调用对象list
的方法listController
,其上下文为window
(全局)。
之所以发生这种情况,是因为您通过这种方式调用了方法:executeAction listController.list
而来自executeAction
这只是方法调用方法:action(args)
您可以将方法绑定到类(使用_.bind
)或使用js call
的{{1}}或apply
方法(绑定方式更容易):
绑定(Function
:
_.bind(action, context)
使用其他上下文(executeAction _.bind(listController.list, listController)
或method.call(context, arg1, ..)
)
method.apply(context, argsArray)
答案 1 :(得分:1)
你应该在初始化函数中使用_.bindAll(this)
,只需添加:
initialize:->
_.bindAll(this, "list") // Like @mu mentioned in the comment, function name is required
修改强>:
虽然@ KiT-O是正确的,但调用者可以使用_.bind
函数将函数绑定到Controller。这不应该是调用者的责任,函数需要绑定到正确的上下文,调用者不应该关心/知道它。
这就是为什么我更喜欢_.bindAll
解决方案,尽管它为Backbone添加了更多的样板代码
答案 2 :(得分:0)
this
在调用函数之前不受约束,并且取决于函数的调用方式。您可以将其视为隐式传递给函数的额外参数。
在这种情况下,我认为您正在使用controller()
调用您的函数。 this
值可以通过调用函数作为方法(如foo.bar()
或foo["bar"]()
)或通过call()
或apply()
显式设置来设置。你的调用都没有,所以这会恢复为全局对象。
来自here。