LoginSignup
3
3

More than 5 years have passed since last update.

Angular 2 の Viewport Directive 文法の謎

Last updated at Posted at 2015-03-22

(Angular 2 の alpha.13 に基づいた内容です。)

昨日 ng-japan に参加した際に Angular 2 に触ってみたのですが、If とか Foreach の書き方が謎だったので調べてみました。

ちなみに Viewport Directive というのは、以前 Template Directive と呼ばれていた Angular 2 の 3 種類の Directive のうちの一つで、HTML に新しい DOM を挿入するものです。If, Foreach はこれに当たります。

書き方のバリエーション

If は、以下のどれでもいいそうです。

<template [if]="foo">
  <p>Show me!</p>
</template>

<p template="if: foo">Show me!</p>

<p *if="foo">Show me!</p>

Foreach も、以下のどれでもいいそうです。

<template foreach #foo [in]="foos">
  <li>{{foo.text}}</li>
</template>

<li template="foreach #foo in foos">{{foo.text}}</li>

<li *foreach="#foo in foos">{{foo.text}}</li>

え、なにそれ、どういうこと?

<template></template> への正規化と microsyntax

If, Foreach などの実装は https://github.com/angular/angular/tree/2.0.0-alpha.13/modules/angular2/src/directives にあるので読んでみました。

If は if という属性があるかとその値しか見ていないし、Foreach も(概ね) foreachin という属性があるかと in の値しか見てません。ということは、Directive がテンプレートの処理を開始する前に、一番上の <template></template> の形式に正規化されているということです。

ViewSplitter なるもので、以下の変換をしているようです。

  1. * から始まる属性値を template 属性に。例えば *foreach="#foo in foos" -> template="foreach #foo in foos"
  2. template="" の属性値(microsyntax)をパースし、<template></template> を作ってその属性を設定。例えば template="foreach #foo in foos" -> <template foreach #foo [in]="foos"></template>

なので、上の例だと下のものから順に上に変換されているイメージです。

2 の microsyntax のパースの部分は、ドキュメントだけ読むとよく意味がわかりませんが、コードテストを読んだところ、結局一定のルールに従って <template></template> に設定するための複数の属性を取り出すよ、ということのようです。

Viewport Directive の仕組み

<template></template> の書き方の面白いところは、ただの属性なので順番はどうでもいいという点です。以下のどれでもいいわけですね。

<template foreach #foo [in]="foos"></template>
<template foreach #foo [in]="foos"></template>
<template #foo foreach [in]="foos"></template>
<template #foo [in]="foos" foreach></template>
<template [in]="foos" foreach #foo></template>
<template [in]="foos" #foo foreach></template>

ちなみに #foo は implicit variable というらしく、Directive の方では \$implicit という名前の local を設定すればそこに値を渡せる模様。

結論

他人の書いた Viewport Directive を使うときは安心して *foreach="" のような形式が使えます。要素が複数の時は <template></template> で囲む必要がありますが。

自分で Viewport Directive を作るときは、例の microsyntax でいい感じに書けるように、使う属性をうまく決める、という感じでしょうか。

とりあえずすっきり。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3