Javascript CoffeeScript类中的修饰函数
我正在编写一个主干应用程序,我想编写一个经过身份验证的decorator,可以用来修饰router类中的方法(路由)列表 所以我有一个路由器,有一些方法,并尝试过类似的东西。但是,当我调用我想要装饰的路线时,装饰器没有连接Javascript CoffeeScript类中的修饰函数,javascript,backbone.js,coffeescript,decorator,Javascript,Backbone.js,Coffeescript,Decorator,我正在编写一个主干应用程序,我想编写一个经过身份验证的decorator,可以用来修饰router类中的方法(路由)列表 所以我有一个路由器,有一些方法,并尝试过类似的东西。但是,当我调用我想要装饰的路线时,装饰器没有连接 class MyApp extends Backbone.Router routes: '' : 'home' 'foo' : 'foo' 'bar' : 'bar' authenticated: [
class MyApp extends Backbone.Router
routes:
'' : 'home'
'foo' : 'foo'
'bar' : 'bar'
authenticated: ['foo', 'bar']
initialize: ->
@decorateAuthenticatedFunctions()
decorateAuthenticatedFunctions: =>
_.each @authenticated, (method)=>
@[method] = (args)=>
if @authorized()
@[method].apply @, args
else
@navigate '', true
authorized: =>
@user? and @user.loggedIn
foo: =>
#do stuff
bar: =>
#do stuff
如何解决此问题?我认为您遇到了
此
上下文问题
请记住,“胖箭头”在函数定义时绑定到this
。因此,您的decoreauthenticated函数:=>
将绑定到全局this
,而您希望将其绑定到您的MyApp
实例
试试这个:
...
initialize: ->
@decorateAuthenticatedFunctions.call(@) # Call with proper context
decorateAuthenticatedFunctions: -> # Use skinny arrow
_.each @authenticated, (method)=>
@[method] = (args)=>
if @authorized()
@[method].apply @, args
else
@navigate '', true
authorized: -> # Use skinny arrow
@user? and @user.loggedIn
...
你有一些问题 首先,我不认为
initialize
会因为某种原因被调用。我可以判断,因为如果它被调用,那么它将引发错误(见下一点)。现在我不是骨干专家,但也许可以尝试使用构造函数来代替
class MyApp extends Backbone.Router
constructor: ->
super
@decorateAuthenticatedFunctions()
第二,这个循环不起作用。您将用一个新函数替换@[method]
,该函数在该函数中调用@[method]
。当它成功时,您将得到一个递归无限函数调用。因此,保存对原始函数的引用,然后使用decorator函数调用该引用
当你们在那个里的时候,不需要下划线,因为coffee脚本做循环非常好。你甚至不需要这个循环的闭包,因为你只需要立即使用循环值
这一稍作改动的非主干版本适用于:
是否确实正在调用
initialize
?在那里添加console.log警报以确保。方法声明上的=>
工作方式不同。相反,它确保此
始终是实例。六羟甲基三聚氰胺六甲醚。。。我想你是对的。我仍然建议通过调试和decorateAuthenticatedFunctions
顶部的break
ing来分析this
上下文。您不想提供自己的构造函数。主干机器将调用初始化
。不过,他在他的else
上遗漏了一些缩进,这可能会导致一些意外行为。使用有一个优点。每个都将使用本地forEach
(如果可用)。
class MyApp
authenticated: ['foo', 'bar']
constructor: ->
@decorateAuthenticatedFunctions()
decorateAuthenticatedFunctions: =>
for method in @authenticated
fn = @[method]
@[method] = (args) =>
if @authorized()
fn.apply @, args
else
console.log 'denied'
authorized: =>
@user? and @user.loggedIn
foo: =>
console.log 'foo'
bar: =>
console.log 'bar'
app = new MyApp
app.user = { loggedIn: no }
app.foo() # denied
app.bar() # denied
app.user = { loggedIn: yes }
app.foo() # foo
app.bar() # bar