Mainly Devel Notes

Twitter, GitHub, StackOverflow: @ovrmrw (short hand of "overmorrow" that means the day after tomorrow)

Angular2がalpha.50になってインストールとかRxJSとか色々めんどくさい(beta.0になりました)

Angular2, npm3, RxJS, TypeScript, System.js

【beta.0対応版】

Angular2はalpha.47まではそこまでBreaking Changesが無かったような気がするのですが、ここ最近のアップデートはガンガンBreakingしています。

angular2-polyfills.jsの読み込みが必要になった

alpha.54からはangular2.dev.jsの前にポリフィルの読み込みが必要になりました。

<script src="../node_modules/angular2/bundles/angular2-polyfills.min.js"></script>
<script src="../node_modules/angular2/bundles/angular2.dev.js"></script>

これが足りないといくらブラウザをリロードしても真っ白な画面のままです。気を付けましょう。

npm3だとAngular2のインストールがめんどくさい

2.0.0-alpha.50からAngular2のインストール時に依存パッケージが自動インストールされなくなりました。(npm3だけらしい)
なのでこのように依存パッケージを先にインストールするようにnpm installを書きます。

npm i es6-promise@^3.0.2 es6-shim@^0.33.3  --save
npm i reflect-metadata@0.1.2 rxjs@5.0.0-beta.0 zone.js@0.5.10 --save --save-exact
npm i angular2 --save 

RxJSでイベントハンドラを書こうとするとめんどくさい

RxJS公式GitHubの説明通りにtsファイルの中でこのように書くと、

// hoge.ts

import Rx from 'rxjs/Rx'

Rx のところが赤い波線エラーになるかと思います。alpha.53まではちょこちょこいじってなんとかなっていたのですが…

いよいよalpha.54から、この↑書き方をするとAngular2では挙動がおかしくなりました。なのでこう書きます。

// hoge.ts

import {Observable} from 'rxjs/Observable'
import 'rxjs/add/observable/fromEvent'
import 'rxjs/add/observable/timer'
import 'rxjs/add/operator/map'
import 'rxjs/add/operator/filter'
import 'rxjs/add/operator/debounce'
import 'rxjs/add/operator/toPromise'

・・・こんな感じで使用するオペレーターを全て個別にimportします。
ぼくだってほんとうはこんなことしたくなかった。

オペレーターに関しては最初に読み込むJSファイル(例えばapp.jsとか)でまとめてimportしておけばルーティングで他のページに遷移しても有効みたいです。それだけが救いですね。

あとHTMLファイルで'Rx.js'を読み込んでおく必要があります。

<script src="../node_modules/rxjs/bundles/Rx.js"></script>

サンプルコード↓(beta.0で動作確認済み)

import {Component} from 'angular2/core'
import _ from 'lodash'
//import {Observable} from 'angular2/angular2' ← 実行時にオペレーターが見つからないエラー連発
//import {Observable} from 'angular2/core' ← 実行時にオペレーターが見つからないエラー連発
//import {Observable} from '@reactivex/rxjs' ← RxJSのバージョンアップによりフォルダ構成が変わった
import {Observable} from 'rxjs/Observable'
import 'rxjs/add/observable/fromEvent'
import 'rxjs/add/observable/timer' // 必要なら
import 'rxjs/add/operator/map'
import 'rxjs/add/operator/filter'
import 'rxjs/add/operator/debounce' // 必要なら
import 'rxjs/add/operator/toPromise' // 必要なら

@Component({
  selector: 'my-app',
  template: `
    <!-- 省略 -->
  `
})
export class Foo {
  initEventObservables(): void {
    Observable.fromEvent<MouseEvent>(document, 'click')
      .map(event => event.target.textContent)
      .filter(text => _.trim(text).length > 0)
      .subscribe(text => {
        alert('You clicked ' + text);
      });
  }
}