albatrosary's blog

Azure と Angular と Wercker CI とか

Gross! Angular2 Template Syntax

ちょっときもいAngular2のTemplate Syntaxですが、、確かにキモい、キモすぎる。[]だったり()だったり*とか。このあたりの概要が結構整ってます。

f:id:albatrosary:20160414165620p:plain

angular.io

ざっと目を通してみる

多くはtemplateとclassとのデータのやり取りはダブルカーリー{{}}で記載するのが容易ですね。

import {Component} from 'angular2/core'

@Component({
  selector: 'my-app',
  template: `
    <h1>My First {{name}} {{1+1}} App</h1>
  `
})

export class AppComponent {
  public name = 'Angular';
}

One-wayバインディング

さて、この方法でtextボックスのvalueに値を詰め込む

@Component({
  selector: 'my-app',
  template: `
     <input type="text" value="{{name}}">
  `
})

この書き方はAngular2のキモい書き方でも出来る

@Component({
  selector: 'my-app',
  template: `
    <input type="text" [value]="name">
  `
})

この2つは同じ意味です。どうもHTML5をバリっとやっている人には両方ともキモい。のでこれはどうだろう

@Component({
  selector: 'my-app',
  template: `
    <input type="text" bind-value="name">
  `
})

まぁまぁじゃないか。

Two-wayバインディング

さて、ここまでは何も言わなかったけど「One-way from data source to view target」です。では「Two-way」は?

@Component({
  selector: 'my-app',
  template: `
    <input type="text" [(value)]="name">
  `
})

でた!最悪のキモさ[()]。これもそれなりに感じ良く書ける

@Component({
  selector: 'my-app',
  template: `
    <input type="text" bindon-value="name">
  `
})

まぁいいじゃないか。

attributeへのバインディング

input type="text"valueに「name」から取得した値を入れたわけだがタグのattributeに対しても値を入れ込むことができ「attr.xxxx」を使う。

@Component({
  selector: 'my-app',
  template: `
    <input type="text" [attr.aria-label]="actionName" bindon-value="name">
  `
})

ブラウザでは

 <input type="text" aria-label="actionNameの値">

のように表示されていると思う。

前半の話同様templateはこれすべて同じ意味です

  template: `
    <button [attr.aria-label]="actionName">{{name}} with Aria</button>
    <button attr.aria-label="{{actionName}}">{{name}} with Aria</button>
    <button bind-attr.aria-label="actionName">{{name}} with Aria</button>
  `

Event

ご存知の通りAngular2でイベントは(Event)と記載する

@Component({
  selector: 'my-app',
  template: `
    <button (click)="clicked()">Click1</button>
  `
})

export class AppComponent {
  clicked(event) {
    console.log('clicked');
  }
}

これもキモいのでキモくない書き方をする。

@Component({
  selector: 'my-app',
  template: `
    <button on-click="clicked()">Click2</button>
  `
})

export class AppComponent {
  clicked(event) {
    console.log('clicked');
  }
}

いいね

Distinctive Syntaxのまとめ

Angular2のサイトに一覧がある

f:id:albatrosary:20160414172942p:plain

* Syntax

*は結構つらい(見てるのが)。サンプルだと

<hero-detail *ngFor="#hero of heroes; trackBy:trackByHeroes" [hero]="hero"></hero-detail>

Angular2(2.0.0-beta.15)のsrc/compiler/template_parser.js:L45-L46を見ると

var TEMPLATE_ELEMENT = 'template';
var TEMPLATE_ATTR = 'template';
var TEMPLATE_ATTR_PREFIX = '*';

そしてL293-L300

        var templateBindingsSource = null;
        if (attr.name == TEMPLATE_ATTR) {
            templateBindingsSource = attr.value;
        }
        else if (attr.name.startsWith(TEMPLATE_ATTR_PREFIX)) {
            var key = attr.name.substring(TEMPLATE_ATTR_PREFIX.length); // remove the star
            templateBindingsSource = (attr.value.length == 0) ? key : key + ' ' + attr.value;
        }

って書いてあるのは期待ありで、実際にtemplateを使って

<hero-detail template="ngFor #hero of heroes; trackBy:trackByHeroes" [hero]="hero"></hero-detail>

とか

<template ngFor #hero [ngForOf]="heroes" [ngForTrackBy]="trackByHeroes">
  <hero-detail [hero]="hero"></hero-detail>
</template>

とかいうように書ける。結構キモくないね

最後に

キモいキモくないという感じで書きましたが、通常はキモい方で書くんでしょうね。諦めましょう!(しらんけど)

参考資料

Angular2のサイト以外にもこちらを見たので貼り付けておく

Angular 2 Data Binding – AngularTypescript

Templates · Learn Angular 2