3

我想通过使用 mixins 来拆分一个大类。

我正在使用Little Book中的这个 mixin 代码

@include: (obj) ->
    for key, value of obj when key not in moduleKeywords
      # Assign properties to the prototype
      @::[key] = value

    obj.included?.apply(@)
    this

class FooMixin

  b: => @something = 2

class Foo extends Module
  @include FooMixin

  a: => @something = 1

问题是@in FooMixinis FooMixin。我希望它是Foo

我尝试_.bind(@::[key], @)在末尾添加该行,@include()但没有帮助。有什么建议么?

4

1 回答 1

4

好吧,我做错了几件事。

1.

@include来自小书的对象不是类。要让它与你需要编写的类一起工作@include FooMixin::。但是,我从那以后开始使用对象。

2.

当使用对象而不是类时,粗箭头会在 CoffeeScript 包装器的顶部添加一行,内容为_this = this. 所有方法都绑定到全局上下文,这不是我们想要的。为了解决这个问题,我们必须将粗箭头转换为细箭头,并将每个函数绑定到我们的Foo实例。使用下划线我将它添加到构造函数中Foo

constructor: ->
  for fname in _.functions FooMixin
    @[fname] = _.bind @[fname], @
  super

我试过_.bindAll @, _.functions FooMixin了,但它给了我一个错误,说类似At Function.bind, could not run bind of undefined.奇怪的错误,因为上面的代码与方法几乎相同_.bindAll

所以现在我可以拆分我的类以获得更好的可读性和代码共享。


更新: _.bindAll 的问题在于它需要一个 splat 而不是一个数组。修复是使用_.bindAll @, _.functions(FooMixin)....

更新:找到了更好的解决方案。

与原帖相同。使用混合类。

使用@include FooMixin::或更改@include以对原型而不是属性进行操作。

Foo构造函数中写入FooMixin.call @正确绑定方法。

这很好用,而且很干净。

唯一的潜在问题是 mixins 将被现有属性覆盖。我可以看到解决这个问题的唯一方法是执行以下操作:

after = ->
  _.extend Foo, FooMixin::

class Foo
   # define...

after()

或者将 extend 方法传递给,_.defer但这太难了,可能行不通。

于 2012-10-11T14:10:03.387 回答