Angular Info

Beta.8がリリースされました

どうも、らこです。予想通り今週はBeta.8がリリースされましたので、主な変更点をさらっていこうと思います。

ComponentRouter(Angular 1用)の破壊的変更

Angular 1向けのComponent Routerに破壊的な変更が入りました。DIの文字列が大きく変わっています。
$routeから$rootRouterに、routerから$routerになっているので、要注意です。
また、templateUrlを持つcomponentにルーティングできなかったバグが修正されています。

trackByのバグ修正

ngFortrackByでインデックスを使った際に配列の操作で容易にChange Detectorが壊れるバグが修正されました
いろいろ危なっかしい実装だったので心配してましたがようやく安心してtrackByできます。

ちなみにAngular 1でもAngular 2でも共通する話ですが、ng-repeatngFortrackByを使うと目に見えてパフォーマンスが上がります。
配列の変更検知をするためには「どの要素」が変わったのかを効率よく調べないと全要素舐め直すことになるので、
一意性の調べ方をこちらで提供してあげるとめっちゃ早くなります。前にも貼った気がしますが、
Is Angular 2 faster ? · Issue #7088 · angular/angular
では最初に「track byしたng-repeat」と「素のngFor」を比較してAngular 2が本当に速いのか疑問を投げかけていますが、
ngFortrackByを併用すると明らかにAngular 2のほうが速くなっていることがわかりました。

要素数が多く、変更も多いパフォーマンスのネックになりがちな部分にはtrackByをつけるようにしましょう。

QueryList#forEach()の実装

TypeScript/JavaScript側のQueryListにはなかったforEachメソッドが追加されました。ちなみに私が実装しました。

Dart版ではQueryListIterableMixinクラスを継承しているのでそのままforEachが暗黙のうちに生えていたのですが、
TS/JSでは単なるクラスなので、APIに差ができてしまっていました。

デバッグ用のAPIが新しく追加された

デバッグ用のAPIが3つも増えました。

  • window.getAllAngularRootElements() : ページ上でangular.bootstrap()の対象となっているルートエレメントを取得できる
  • ng.coreTokens.ApplicationRef : ApplicationRefの参照が取れる
  • ng.coreTokens.Ngzone : NgZoneの参照が取れる

ng.proveと合わせたこれらデバッグAPIの使い方は近いうちに別に特集しようと思います。

Dart版でジェネリクスを使ったDIの廃止

Dart版のみで、ジェネリック付きの型がDIできなくなりました。背景にはOffline Template Compiler周りの実装の障害になったことがあるようです。

patternバリデータの追加

ビルトインのバリデータにpatternバリデータが追加されました。input要素のバリデーションに正規表現でパターンを指定できます。

<input [ngControl]="fullName" pattern="[a-zA-Z ]*">

i18n機能のPipeの追加

i18n用に新しくi18nPlurali18nSelectの2つのPipeが追加されました。

i18nPlural

i18nPluralは数値に関するi18n対応を担います。数値の値によって文字列の単数形、複数形を対応させる際に使えます。

<div>
  {{ messages.length | i18nPlural: messageMapping }}
</div>

class MyApp {
  messages: any[];
  messageMapping: any = {
    '=0': 'No messages.',
    '=1': 'One message.',
    'other': '# messages.'
  }
  ...
}

i18nSelect

i18nSelectは文字列に関するi18n対応を担います。文字列の値によって表現を変える部分に有用です。
次の例ではgenderの値によってテキストの中のherhimを切り替えています。

<div>
  {{ gender | i18nSelect: inviteMap }}
</div>

class MyApp {
  gender: string = 'male';
  inviteMap: any = {
    'male': 'Invite her.',
    'female': 'Invite him.',
    'other': 'Invite them.'
  }
  ...
}

replace Pipeの追加

文字列を置換するreplace Pipeが追加されました。

{{ expression | replace:pattern:replacement }}

という形式で記述できます。具体的には次のようになります。

<div>
  {{ 'abcdef' | replace:abcPattern:'ABC' }}
</div>

class MyApp {
  abcPattern = /abc/g;
}

実行すると ABCdef という風に置換されます。挙動はString.prototype.replaceと互換があります。


今週は便利なAPIがたくさん増えました。こういうアップデートは久々なので良いリファクタリングの機会かもしれません。

ちなみにBeta.9のリリースからはいよいよrouterの改革が始まります。routerLinkのDSLが徐々に廃止され、正規表現と関数によってルーティングが記述できるようになります。

破壊的変更にはしないらしいのでゆったり構えておきましょう。

参考資料