さて、私が間違っていたことはほとんどありません。
1.
@include
from the Little Book は、クラスではなくオブジェクトを取ります。クラスで動作させるには、@include FooMixin::
. しかし、それ以来、代わりにオブジェクトを使い始めました。
2.
クラスの代わりにオブジェクトを使用する場合、太い矢印は、CoffeeScript ラッパー内の一番上に行を追加します_this = this
。すべてのメソッドは、私たちが望むものではないグローバル コンテキストにバインドされています。修正するには、太い矢印を細い矢印に変換し、各関数をFoo
インスタンスにバインドする必要があります。Underscore を使用して、これを のコンストラクターに追加しました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 の問題は、配列ではなくスプラットを取ることです。を使用することを修正します_.bindAll @, _.functions(FooMixin)...
。
更新:より良い解決策が見つかりました。
元の投稿と同じ。ミックスインにクラスを使用します。
プロパティの代わりにプロトタイプを操作するために使用@include FooMixin::
または変更します。@include
Foo
コンストラクターで、メソッドを正しくバインドするように記述しFooMixin.call @
ます。
これはうまく機能し、素晴らしくきれいです。
唯一の潜在的な問題は、ミックスインが既存のプロパティによってオーバーライドされることです。私が見ることができるこれを回避する唯一の方法は、次のようなことをすることです:
after = ->
_.extend Foo, FooMixin::
class Foo
# define...
after()
または、extend メソッドを に渡します_.defer
が、これは非常にハックで、おそらく機能しません。