Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript CoffeeScript类中的修饰函数_Javascript_Backbone.js_Coffeescript_Decorator - Fatal编程技术网

Javascript CoffeeScript类中的修饰函数

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: [

我正在编写一个主干应用程序,我想编写一个经过身份验证的decorator,可以用来修饰router类中的方法(路由)列表

所以我有一个路由器,有一些方法,并尝试过类似的东西。但是,当我调用我想要装饰的路线时,装饰器没有连接

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​