Riot.js(ver:2.3.12 時点)のループ処理で、入れ子のループをする場合に親の情報を引き継いじゃって困ったのでメモ。
公式にある方法で単純にループを入れ子にすると、スコープ(?)がおかしくなる。
ダメな例
<todo></todo><!-- 表示先 -->
<script type="riot/tag">
<todo>
<ul>
<li each={ items } class={ completed: done }>
<input type="checkbox" checked={ done }> { title }
<ul if={ child }>
<li each={ child } class={ completed: done }>
<input type="checkbox" checked={ done }> { title }
</li>
</ul>
</li>
</ul>
this.items = [
{
title: 'First item',
done: true
},
{
title: 'Second item',
done: true,
child: [
{
title: 'Fourth item'
// ここは done がない(チェック入れない)
}
]
},
{
title: 'Third item'
}
]
</todo>
</script>
上記の結果は、done:true
がないはずの「Fourth item」にもチェックが付く。
たぶん、「Fourth item」に done
がないために「Second item」の done:true
が伝播しちゃってるんだと思う。
いろいろ試したところ、単純な each={ items }
のループではなく、in
をつかった each={ item in items }
で変数化しとくと大丈夫そう。
ちゃんとなる例
<todo></todo><!-- 表示先 -->
<script type="riot/tag">
<todo>
<ul>
<!-- ループに in (for...in) を使うべし -->
<li each={ item in items } class={ completed: item.done }>
<input type="checkbox" checked={ item.done }> { item.title }
<ul if={ item.child }>
<!-- in を使えば同じキー名でもOK -->
<li each={ item in item.child } class={ completed: item.done }>
<input type="checkbox" checked={ item.done }> { item.title }
</li>
</ul>
</li>
</ul>
this.items = [
{
title: 'First item',
done: true
},
{
title: 'Second item',
done: true,
child: [
{
title: 'Fourth item'
// ここは done がない(チェック入れない)
}
]
},
{
title: 'Third item'
}
]
</todo>
</script>
よかったよかった。