ほぼメモ書きです。
class shorthandを使うとコンパイルエラーになる
class={ disabled: true }
みたいに書くやつのことです。
exprオプションを付けてコンパイルするとCoffeeScriptコンパイラが余計にコンパイルしてしまうようです。
class={^ disabled: true }
と書きましょう。
また、pugのコンパイラでもエラーになるので、class="{^ disabled: true }"
のように書くのが最も確実です。
CoffeeScriptの件は本家のissueに載ってます。
interpolationが被る
これは公式ガイドのサンプルを書き直してたときにものすごくはまりました…。
<form onsubmit={ add }>
<input ref="input" onkeyup={ edit }>
<button disabled={ !text }>Add #{ items.length + 1 }</button>
</form>
form(onSubmit="{ add }")
input(ref="input" onKeyUp="{ edit }")
button(disabled="{ !text }")
| Add #{ items.length + 1 }
と直したわけですが、これはコンパイルエラーになります。
この場合はたまたまなんですが、Add #{ items.length + 1 }
の#{ }
がpugのinterpolationの構文と被ってしまったわけです。
多少気持ち悪いですがAdd { '#' + (items.length + 1) }
とすることで回避できます。
あとはコンパイルオプションでriot側のブラケットを{ }
以外にしてあげてもOKです。
ただ、pugとCoffeeScriptのinterpolationは被ったままどうしようもないので、script内でinterpolationを使おうものなら容赦なくコンパイルエラーになります…。
筆者はriotifyを使ってモジュール分割し、処理の大半を別のCoffeeScriptファイルに書き出すことでとりあえず逃げています。
このあたり上手い方法をご存知の方がいらっしゃいましたら是非コメントいただけると助かります…!
暗黙的なthisを明示する
上記と同じく公式ガイドより。
<script>
this.items = opts.items
edit(e) {
this.text = e.target.value
}
add(e) {
e.preventDefault()
if (this.text) {
this.items.push({ title: this.text })
this.text = this.refs.input.value = ''
}
}
toggle(e) {
var item = e.item
item.done = !item.done
}
</script>
script.
@items = opts.items ? []
edit = (e) ->
@text = e.target.value
add = (e) ->
e.preventDefault()
if @text
@items.push title: this.text
@text = @refs.input.value = ''
toggle = (e) ->
item = e.item
item.done = not item.done
またもやこれだと動かないのです。
どうやらJavaScriptの性質で関数がその場の名前空間(this)にバインドされていたようです。
そのため、
@edit = (e) ->
@text = e.target.value
のように関数(を格納している変数)の頭に@
(this)をつけてあげればOKです。
さいごに
たくさんの括弧を見ると吐き気がする持病をお持ちの方、終了タグなんて書きたくないというものぐさな方(両方筆者のことですが)には天国のようなコードが書けるので、気が向いたら試してみてください。