Riot+CoffeeScriptで転んだ


こんなのを

my-tag.tag(type=none)
<my-tag>
  <input value={value}>
  <button each={list} onclick={click}>{name}</button>
  <script>
  this.value = 'initial'
  this.list = [
    {name: 'btn-1', value: 'update 1'},
    {name: 'btn-2', value: 'update 2'}
  ];
  click(e) {
    this.value = e.item.value
  }
  </script>
</my-tag>

こうしたら

my-tag.tag(type=coffee)
<my-tag>
  <input value={value}>
  <button each={list} onclick={click}>{name}</button>
  <script type="coffee">
  @value = 'initial'
  @list = [
    {name: 'btn-1', value: 'update 1'}
    {name: 'btn-2', value: 'update 2'}
  ]
  @click = (e) ->
    @value = e.item.value
  </script>
</my-tag>

valueが変わらなくなってしまった

それぞれコンパイル後のファイル(以下比較のため整形済み)を見比べてみたら

my-tag.js(type=none)
riot.tag(
  'my-tag',
  '<input value="{value}"><button each="{list}" onclick="{click}">{name}</button>',
  function(opts) {
    this.value = 'initial'
    this.list = [
      {name: 'btn-1', value: 'update 1'},
      {name: 'btn-2', value: 'update 2'}
    ];
    this.click = function(e) {
      this.value = e.item.value
    }.bind(this);
  }
);
my-tag.js(type=coffee)
riot.tag(
  'my-tag',
  '<input value="{value}"><button each="{list}" onclick="{click}">{name}</button>',
  function(opts) {
    this.value = 'initial';
    this.list = [
      {name: 'btn-1', value: 'update 1'},
      {name: 'btn-2', value: 'update 2'}
    ];
    this.click = function(e) {
      return this.value = e.item.value;
    };
  }
);

改行やスペースを除くと相違点は.bind(this) (とreturn)のみだった
ので

my-tag.tag(type=coffee)
# 〜略〜
  @click = ((e) ->
    @value = e.item.value
  ).bind @
# 〜略〜
</my-tag>

のように修正したところ正常に動くようになった


eachの中でなければbindの必要は無い
が、純riotの場合と揃えるため毎回bindしといたほうがいい気がする
そのうちコンパイラ読もう