| AngularJS | TypeScript | Google Cloud Platform | Bootstrap | Flask | ブログカテゴリ(Angular) |
Angularに関連するブログエントリ=
準備
Quickスタート
- > git clone https://github.com/angular/quickstart.git quickstart
- > cd quickstart
- > npm install
- > npm start
要素
ルートモジュール
要素名 |
説明
|
コンポーネント |
UI部品
|
サービス |
ビジネスロジック
|
パイプ |
表示値の加工、演算
|
ディレクティブ |
文書ツリーの操作
|
- モジュール
- Angularにおけるモジュールの実態は、TypeScriptのクラス
- 定義しただけではモジュールとみなされず、@NgModuleデコレータで宣言が必要
設定ファイル
設定ファイル |
概要
|
package.json |
利用するライブラリ情報
|
tsconfig.json |
TypeScriptコンパイラーの動作を
|
systemjs.config.js |
モジュールローダー(SystemJS)の設定
|
インストール
- >npm install -g @angular/cli
アプリケーションの生成
- > ng new myapp
アプリケーションの実行
- > ng serve
概要
|
コマンド
|
appアプリを生成
|
ng new app
|
ひな形の生成
|
ng generate ...
|
ビルドして起動
|
ng serve
|
ビルド
|
ng build
|
ユニットテスト
|
ng test
|
E2Eテスト
|
mg e2e
|
i118nメッセージを抽出
|
ng xi18n
|
指定されたキーワードで検索
|
ng doc keyword
|
TSLintによるコードチェック
|
ng lint
|
現在の設定を取得
|
ng get key
|
指定されたキー/値を設定
|
ng set key=value
|
Angular CLIのバージョン
|
ng version
|
オブジェクト生成 ng generate サブコマンド
要素
|
コマンド
|
モジュール
|
ng g moduole hoge
|
コンポーネント
|
ng g component hoge
|
ディレクティブ
|
ng g directive hoge
|
パイプ
|
ng g pipe hoge
|
サービス
|
ng g service hoge
|
ガード
|
ng g guard hoge
|
クラス
|
ng g class hoge
|
インターフェース
|
ng g interface hoge
|
列挙
|
ng g enum hoge
|
ngx-bootstrap
インストール
- npm install ngx-bootstrap bootstrap --save
src/app/app.module.ts の編集
- import { AlertModule } from 'ngx-bootstrap';
- :
- @NgModule({
- :
- imports: [AlertModule.forRoot(), ... ],
- :
- })
.angular-cli.json に以下を追加
- "styles": [
- "../node_modules/bootstrap/dist/css/bootstrap.min.css",
- "styles.css"
- ],
src/app/app.component.html に以下を追加
- <alert type="success">hello</alert>
- $ ng add @angular/material
カスタムテーマ
非同期通信
app.module.ts
- import { HttpModule } from '@angular/http';
- :
- @NgModule({
- :
- imports: [
- :
- HttpModule,
- ],
- :
- })
データバインディング
構文
データ方向
|
種類
|
記法
|
コンポーネント -> ビュー
|
Interpolation(補間)
|
- {{...}}
|
コンポーネント -> ビュー
|
プロパティ/属性バインディング
|
- [property]='value'
|
ビュー -> コンポーネント
|
イベントバインディング
|
- (event)='handler'
|
コンポーネント <-> ビュー
|
双方向バインディング
|
- [(target)]='value'
|
フォーム要素
|
input/textarea/selectなど,
フォーム要素をバインドするには、ngModel を利用する
|
- <textarea [(ngModel)]="memo"></textarea>
|
テンプレート参照変数
- テンプレート内の特定の要素を参照するための変数
- 与えられた変数経由でプロパティなどにアクセス
- #変数名
- (change)="0"は、イベントトリガーで値を更新するため必要
- <input #txtHoge type="text" (change)="0"/>
- <div>{{txtHoge.value}}</div>
双方向バインディング
- ビューの値とコンポーネントの値を双方向に同期させる
- AngularでForm要素を操作するためには、FormModuleが必要
- import と @NgModule の imports に FormModuleを追加
ルートモジュール(app.modules.ts)
- import { FormsModule } from '@angular/forms';
- :
- @NgModule({
- :
- imports: [
- BrowserModule,
- FormsModule,
- :
ビュー
- input/textarea/selectなどフォーム要素をバインドするには、ngModel を利用する
- このためには、name属性の指定が必須
- ngModelを[(ngModel)]とする
- <select name="selAcion" [(ngModel)]="selectedAction">
- <option *ngFor="let item of testActions" value="{{item}}" >{{item}}</option>
- </select>
コンポーネント
- export class AccountComponent implements OnInit {
- testActions: string[] = [,'login','logout','check'];
- selectedAction: string = ;
入力値の加工
- 上記は、プロパティバインディング、イベントバインディングを組み合わせて、双方向を実現している。
- データバインディング時に値を加工する場合、[(ngModel)] を [ngModel]と(ngModelChagen) に分解
- $eventは入力値そのものを表す
- <input name="hoge" type="text"
- [ngModel] = "hogeName"
- (ngModelChange) = "hogeName=$event.toUpperCase()" />
イベントバインディング
- ビューからコンポーネントに情報を引き渡す仕組み
- イベントとイベントハンドラーの紐付け
- <element (event)="exp"></element>
- 主なevent:click,dblclick,mousedown,mouseup,mouseenter,mousemove,mouseleave,focus,blur,keydown,keypress,keyup,input,select,reset,submit
イベント情報を取得する $event
- イベントハンドラーを呼び出す際に$eventを明示的に渡す必要がある
- <input type="button" (click)="show($event)" value="hoge" />
- イベント処理後デフォルトの動作をキャンセルするには、event.preventDefault
- イベントバブリングを止めるには、event.stopPropagation
- import { Component } from '@angular/core';
- import { componentFactoryName } from '@angular/compiler';
-
- @Component({
- selector: 'app-root',
- templateUrl: './app.component.html',
- styleUrls: ['./app.component.sass']
- })
- export class AppComponent {
- title = 'Hot Dog Status';
- status = ;
- save(e: any) {
- this.status = "Save";
- }
- load(e: any) {
- this.status = "Load";
- }
- }
.
- <h1 id="hotDogStatus">{{title}}:{{status}}</h1>
- <input type="textField" id="latestHotDogStatus" />
- <button (click)="save($event)">Save</button>
- <button (click)="load($event)">Load</button>
-
- <router-outlet></router-outlet>
属性/クラス/スタイルバインディング
- コンポーネント -> ビューへのバインディングはプロパティバインディングが基本
- 状況によりプロパティバインディングができない場合、またコードが冗長になる場合に備え以下が準備されている
属性バインディング
- [attr.name] = "exp"
クラスバインディング
- スタイルクラスに特化し、スタイルの着脱をシンプルに表現できる
- [class.name] = "exp"
スタイルバインディング
- [style.name] = "exp"
- [style.name.unit] = "exp"
- [style.font-size.%] = "size"
Form実装例
ラジオボタン
- <form #myForm="ngForm" (ngSubmit)="onSubmit(myForm)">
- <ng-container *ngFor="let itm of radioSample; index as i">
- <label>
- <input type="radio" name="radioSample"
- [(ngModel)]="selected"
- [value]="item.value" [checked]="selected == itm.value"
- (change)="onRadioChange(i)">{{ itm.label }}
- </label>
- </ng-container>
- <button>submit</button>
- </form>
- selected = "3";
- radioSample = [
- {label:'One', value:'1'},
- {label:'Twe', value:'2'},
- {label:'Three', value:'3'},
- {label:'Four', value:'4'},
- {label:'Five', value:'5'}
- ];
- onRadioChange(index:number) {
- console.log(index);
- }
- onSubmit(form: NgForm) {
- console.log(form.value);
- }
ディレクティブ
- 標準的なHTMLに対して、ngFor、ngStyleなどの独自要素、属性を追加することで機能を付与
- 大きく以下の3種類に分類
分類と主なディレクティブ
種類 | 概要 |
コンポーネント | テンプレートをともなう |
構造ディレクティブ | 要素を追加削除することで、文書ツリーを操作 |
属性ディレクティブ | 属性形式で、要素、コンポーネントの見た目や動作を変更 |
分類 | 名前 | 概要 |
構造 | ngIf | 真偽により表示切り替え |
ngSwitch | 値により表示切り替え |
ngFor | 配列のループ処理 |
ngTemplateOutlet | 用意されたテンプレートの内容をインポート |
ngComponentOutlet | 用意されたコンポーネントをインポート |
属性 | ngStyle | 要素にスタイルプロパティを付与 |
ngClass | 要素にスタイルクラスを着脱 |
ngPlural | 数値に応じて出力切り替え |
ngIf
- <element *ngIf="condition">
- contents
- </element>
- element:任意の要素
- condition:条件式
- contents:条件式が真の時に表示されるコンテンツ
- ngIf=falseは、要素を生成しない(頻繁に表示、非表示を切り替える場合、スタイルバインディングでdisplayを利用する)
- <mat-toolbar *ngIf="isToolbar">...</mat-toolbar>
- export class AppComponent {
- isToolbar = true;
- :
テンプレートを切り替える
- templateはng-templateで宣言できる
- <div *ngIf="flag; then trueContents; else elseContents>この部分は表示されない</div>
- <ng-template #trueContentas>trueの場合表示される</ng-template>
- <ng-template #elseContentas>falseの場合表示される</ng-template>
ngSwitch
- 指定された式の値に応じて、表示すべきコンテンツを切り替え
- 合致がない場合、ngSwitchDefaultを尿字
- <parent [ngSwitch]="exp">
- <child *ngSwitchCase="value1"> ... </child>
- <child *ngSwitchCase="value2"> ... </child>
- :
- <child *ngSwitchDefault> ... </child>
- </parent>
ngFor
- 指定された配列から順に要素を取り出し内容をループする
- 指定された要素を繰り返すが、ng-container というダミーのコンテナに適用すると、含まれる要素一式を繰り返すことができる
- 要素の追加、削除をトラッキングするには、トラッキング式(trackBy関数)を利用し、要素を識別させる
- <element *ngFor="let tmp of list"> ... </element>
ngFor配下で利用できる特殊変数
- 使用する場合、式の中で、index as i のようにローカル変数に代入する必要がある
変数 | 概要 |
index | ループ回数 |
first | 最初の要素か |
last | 最後の要素か |
even | indexが偶数か |
odd | indexが奇数か |
ngStyle
- 複数スタイルをまとめて設定できる
- スタイル指定は、キャメルケースもしくは、ハイフン付き表現を引用符で囲む
- <element [ngStyle]="objStyle"> ... </element>
- @Compnent({
- :
- template: '<div [ngStyle]="style"></div>'
- })
- export class AppComponent {
- style = {
- backgroundColor: '#f00',
- 'font-weight': 'bold'
- };
- }
ngClass
- <element [ngClass]="clazz"> ... </element>
変数 | 概要 |
文字列 | スタイルクラス名(空白区切りで複数指定可) |
配列 | スタイルクラス名のリスト |
オブジェクト | [スタイルクラス名:有効/無効]形式 |
ngPlural
- 式の値がnumに一致する場合、ng-template配下のメッセージを表示する
- <element [ngPlural]="exp">
- <ng-template ngPluralCase="num">message</ng-template>
- :
- </element>
- num : =0,=1,other などを指定できる
ngTemplateOutlet
- 予め用意されたテンプレートをコンポーネントの任意の位置に挿入する
- <ng-container *ngTemplateOutlet="exp; context : ctx"></ng-container>
- exp : テンプレート
- ctx : テンプレートに反映させるオブジェクト
ngComponentOutlet
- 予め用意したコンポーネントを動的にビューにインポートする
- <ng-container *ngComponentOutlet="exp"></ng-container>
フォーム
- Angularでは標準のform/input要素が拡張されている
- 利用するためには、FormsModuleをインポートする
ngForm
- Angularでは標準formが拡張されている
- 以下のような属性を宣言しておく
属性 | 概要 |
#myForm='"ngForm'" | ngFormディレクティブを変数にセット |
(ngSubmit)='"show()'" | サブミット時に呼び出す処理 |
novalidate | HTML5の検証機能を無効化 |
input
- input/rextareaなどのフォーム要素も拡張されている
- <input id="main" name="mail" type="email"
- [(ngModel)]="user.mail"
- required email
- #mail="ngModel" />
属性 | 概要 |
ngModelディレクティブ | コンポーネントプロパティとバインド、検証機能を有効化するために必須 |
name属性 | Angularが内部的にフォーム要素を識別するためのキー、必ず指定 |
#mail='"ngModel'" | テンプレート参照変数、後からフォーム要素の状態にアクセスできる |
required | 必須 |
minlength | 文字列最小値 |
maxlenght | 文字列最大値 |
email | メールアドレス形式 |
pattern | 正規表現パターンにマッチするか |
min | 数値最小値 |
max | 数値最大値 |
ルーティング
適用
プロジェクト作成
- > ng new app --routing
--routing オプションを付与せずにプロジェクトを作成した場合
- /src/app/app-routing.module.ts を追加
- import { NgModule } from '@angular/core';
- import { Routes, RouterModule } from '@angular/router';
-
- const routes: Routes = [];
-
- @NgModule({
- imports: [
- RouterModule.forRoot(routes),
- ],
- exports: [RouterModule]
- })
- export class AppRoutingModule { }
- import { AppRoutingModule } from './app-routing.module';
- :
- @NgModule({
- imports: [
- BrowserModule,
- AppRoutingModule,
- ],
- providers: [],
- /src/app/app.component.spec.ts
- import { RouterTestingModule } from '@angular/router/testing';
- :
- describe('AppComponent', () => {
- beforeEach(async(() => {
- TestBed.configureTestingModule({
- imports: [
- RouterTestingModule
- ],
- declarations: [
- AppComponent
- ],
- }).compileComponents();
- }));
コンポーネント作成
- > ng g component account --routing
ルーティング定義
- import { NgModule } from '@angular/core';
- import { Routes, RouterModule } from '@angular/router';
- import { AccountComponent } from './account/account.component'
-
- const routes: Routes = [
- {
- path: 'account', component: AccountComponent
- }
- ];
-
- @NgModule({
- imports: [
- RouterModule.forRoot(routes),
- ],
- exports: [RouterModule]
- })
- export class AppRoutingModule { }
利用
- <a routerLink="/account">Account</a>
- <router-outlet></router-outlet>
クエリパラメータ
- import { ActivatedRoute } from '@angular/router';
- :
- export class AppComponent implements OnInit {
- isToolbar: boolean = true;
-
- ngOnInit(): void {
- let outer = this;
- this.route.queryParamMap.subscribe(
- paramsMap => {
- const fullscreen = Boolean(paramsMap.get("fullscreen"));
- outer.isToolbar = !fullscreen;
- });
- }
モジュール
- ある程度の規模の場合、コードをモジュールに分割し、関連クラスをまとめておく
- アプリ構成の見通しがよくなる
- 機能の着脱が容易になる
- 起動時に呼び出されるモジュールを、ルートモジュール、またはメインモジュールという(QuickStartのapp.module.tsなど)
定義
- @NgModuleデコレーターを宣言することで、モジュールと見做される
パラメーター名 | 概要 |
imports | 現在のモジュールで利用する他のモジュール |
exports | 現在のモジュールから外部へ公開するコンポーネントなど |
declarations | 現在のモジュールに属するコンポーネントなど |
bootstrap | アプリで最初に起動すべき最上位のコンんポーネント |
id | モジュールのID値 |
コンポーネント
- ページを構成するUI部品
- Angularアプリとは1つ以上のコンポーネントの集合体といえる
- 一般的には複数のコンポーネントを組み合わせてページを構成する
定義
- import { Component } from '@angular/core';
-
- @Component({
- selector: 'my-app',
- template: `<h1>Hello {{name}}&kt;/h1>`,
- })
- export class AppComponent {
- name = 'Angular';
- }
- templateに含まれる テンプレート:... は、Interpolation(補間)と呼ばれ、ビュー変数を埋め込むためのプレースホルダーとして機能する
- Angularでは、コンポーネントの側でデータ(ビュー変数)を用意しておき、テンプレート側でデータを埋め込む場所や表示方法を定義するのが基本となる
- ビュー変数の役割をコンポーネントのプロパティが担う(上記では、nameがプロパティでテンプレートから自由に参照できる変数となる)
パラメータ名 |
概要
|
selector |
コンポーネントを適用すべき要素を表す
|
template |
コンポーネントに適用するビュー
|
ライフサイクル
ライフサイクル
|
内容
|
コンポーネント生成
|
|
コンストラクター
|
|
ngOnChanges
|
@Input経由で入力値が設定/再設定された
|
ngOnInit
|
入力値(@Inputp)が処理された後、コンポーネントの初期化時(最初のngOnChangesメソッドの後で一度だけ)
|
ngDoCheck
|
状態の変更を検出したとき
|
ngAfterContentInit
|
外部コンテンツを初期化した時(最初のngDoCheckメソッドの後で一度だけ)
|
ngAfterContentChecked
|
外部コンテンツの変更をチェックした時
|
ngAfterViewInit
|
現在のコンポーネントと子コンポーネントのビューを生成した時(最初のngAfterContentCheckedメソッドの後で一度だけ)
|
ngAfterViewChecked
|
現在のコンポーネントと子コンポーネントのビューが変更された時
|
ngOnDestroyed
|
コンポーネントが破棄される時
|
コンポーネント破棄
|
|
@ViewChildrenデコレーター : 子コンポーネントを取得
- @ViewChildren(child) prop
@ViewChildデコレーター : 単一の子コンポーネントを取得
- 取得すべきコンポーネントが単一であることが分かっている場合は、配列を返す@ViewChildrenではなく、@ViewChildを利用できる
- child: 取得する子コンポーネント、prop:プロパティ名
- @ViewChild(child) prop
コンポーネントの連携
- 複数のコンポーネントが互いに連携して1つの機能を構成
- @Input() と @Output() を使うことで、 親のコンテキストと子のディレクティブやコンポーネントとの間でデータをシェアすることができます。
- @Input() プロパティは書き込み可能である一方、@Output() プロパティは観測可能です。
@Input デコレーター : コンポーネントを入れ子に配置
- @Component({
- selector: 'parent',
- template: `<div><app-feed-item [feed]="feed"></app-feed-item></div>`
- })
- export class Parent implements OnInit {
- feed: Feed;
- ngOnInit(): void {
- this.feeds = new Feeds();
- }
- }
- 入れ子になったコンポーネントのプロパティに、@Inputを付与することで、親側でセットした値を受け取ることができる
- @Component({
- selector: 'app-feed-item',
- template: `<div>{{feed.title}}</div>`
- })
- export class FeedItemComponent {
- @Input() feed: Feed;
- }
@Outputデコレーター : 子コンポーネントからイベントを受け取る
サービス
- サービスクラスであることの条件は、@Injectable デコレータを付与することのみ。
- @Injectable デコレータは、コンポーネントに対してサービスを引き渡せることを意味する。
登録
- モジュールにサービスを登録する。
- コンポーネントにも登録できる(@Componentデコレーターのprovidersパラメータ)。この場合コンポーネントと子コンポーネントのみで利用できる。
- import { HogeService } from './hoge.service';
-
- @NgModule({
- :
- providers: [HogeService],
- :
- })
依存性注入
- 方法を宣言するのは、@NgModule/@Component デコレータの providersパラメータ
- サービスを提供するためのProviderオブジェクトを登録する
使用する
- 使用するためには、コンストラクタに対応する引数を追加するだけ
- 以下の例の場合、this.hogeService.メソッド で利用可能
- export class FooComponent {
- constructor(
- private hogeService: HogeService
- ){}
- }
Providerであることの条件は以下のプロパティを持つこと
プロパティ
|
内容
|
provide
|
サービスを注入する際に利用するDIトークン
|
useXxxxx
|
サービスの生成方法 例 userClass: XXXX と指定するとクラス XXXX を常にnew でインスタンス化する
|
multi
|
同一のDIトークンに対して複数のProviderを追加するか
|
useXxxx
プロパティ
|
内容
|
useClass
|
指定されたクラスを注入のたびにインスタンス化
|
useValue
|
指定されたオブジェクトを常に引き渡す(同じ値になる)
|
useExisting
|
指定されたトークンのエイリアスを生成
|
useFactory
|
指定されたファクトリー関数で注入の際にオブジェクトを生成
|
useClass
- providers: [
- { provide: HogeService, useClass: HogeService }
- ]
useValue
- 常に同じオブジェクトを注入する
- クラスのインスタンスを渡す
- providers: [
- { provide: HogeService, useVlaue: new HogeService() }
- ]
useExisting
- providers: [
- { provide: HogeService, useClass: HogeService }、
- { provide: HogeAliasService, useExisting: HogeService }、
- ]
<blockquote>互換性維持など、別のトークンから同一インスタンスを取得したい場合などに利用</blockquote>
useFactory
- providers: [
- { provide: HogeService, useFactory: () => {
- let service = new HogeService();
- service.foo = "bar";
- return service;
- }
- }
- ]
パイプ
- テンプレート上に埋め込まれたデータを加工・整形する
- 与えられた式の値を加工/整形する
呼び出し構文
- {{exp | pipe [:param1 [:param2 ..]]}}
- 式とパイプは、| で区切る
- パイプのパラメーターは、: で列記
- | を重ねることで複数パイプを適用
- {{ price | currency : '¥' }}
標準パイプ
パイプ
|
内容
|
lowercase
|
小文字変換
|
uppercase
|
大文字変換
|
titlecase
|
単語の先頭を大文字変換
|
slice
|
文字列から部分文字列を切り出し
|
date
|
日付・時刻整形
|
number
|
数値を桁区切り
|
percent
|
パーセント形式
|
currency
|
通貨形式
|
json
|
オブジェクトをJSON変換
|
i18nPlural
|
数値によって表示文字列をへんか
|
i18nSelect
|
文字列に応じて出力を切替
|
async
|
Observable/Promiseによる非同期処理の結果を取得
|
作成
- import { Pipe, PipeTransform } from '@angular/core';
-
- @Pipe({
- name: 'globCategory'
- })
- export class GlobCategoryPipe implements PipeTransform {
-
- transform(value: string, ...args: string[]): string {
- if (value != null) {
- const replacement = ((args != null && args[0] != null)?args[0]:'-');
- value = (value.toLowerCase()).replace(/ /g, replacement);
- }
- return value;
- }
- }
- <a *ngFor="let category of feed.categories" href="https://www.typea.info/blog/index.php/category/{{category | globCategory :'_'}}" target="_blank" class="category-link">
- {{category}}
- </a>
Modules
Http
RxJs
リアクティブプログラミングは、データストリームと変更の伝播に関する非同期プログラミングのパラダイムです。
RxJS (Reactive Extensions for JavaScript) は、非同期またはコールバックベースのコード (RxJS Docs) の作成を容易にする
observables を使用したリアクティブプログラミング用のライブラリ
- 非同期処理の既存のコードを observables に変換する
- ストリーム内の値を反復処理する
- 異なる型への値のマッピング
- ストリームのフィルタリング
- 複数のストリームの作成
Observable 作成関数
ベント、タイマー、promise などから observables を作成するプロセスを簡素化
promise から observable を作成
- import { from } from 'rxjs';
-
- // promise から Observable を作成
- const data = from(fetch('/api/endpoint'));
- // 非同期の結果の購読を開始
- data.subscribe({
- next(response) { console.log(response); },
- error(err) { console.error('Error: ' + err); },
- complete() { console.log('Completed'); }
- });
カウンターから observable を作成する
- import { interval } from 'rxjs';
-
- // 一定間隔でで値を発行するObservable を作成
- const secondsCounter = interval(1000);
- // 発行される値の購読を開始
- secondsCounter.subscribe(n =>
- console.log(`It's been ${n} seconds since subscribing!`));
イベントから observable を作成する
- import { fromEvent } from 'rxjs';
-
- const el = document.getElementById('my-element');
-
- // マウスの移動を発行する Observable の作成
- const mouseMoves = fromEvent(el, 'mousemove');
-
- // マウス移動イベントを購読開始
- const subscription = mouseMoves.subscribe((evt: MouseEvent) => {
- console.log(`Coords: ${evt.clientX} X ${evt.clientY}`);
-
- // スクリーンの左端をマウスが越えたら購読中止
- if (evt.clientX < 40 && evt.clientY < 40) {
- subscription.unsubscribe();
- }
- });
AJAX リクエストから observable を作成
- import { ajax } from 'rxjs/ajax';
-
- // AJAXリクエストを生成する Observable の作成
- const apiData = ajax('/api/data');
- // リクエストの生成を購読
- apiData.subscribe(res => console.log(res.status, res.response));
オペレーター
- オペレーターは、コレクションの高度な操作を可能にするために、observables 基盤上に構築される関数です。たとえば RxJS は map()、filter()、concat()、flatMap() のようなオペレーターを定義
- オペレーターは設定オプションをとり、ソースとなる observable を受け取る関数を返します。この返された関数を実行するとき、オペレーターは observable が出力する値を観測、変換し、変換された値の新しい observable を返します
- RxのflatMapの使い方
Map operator
- import { map } from 'rxjs/operators';
-
- const nums = of(1, 2, 3);
-
- const squareValues = map((val: number) => val * val);
- const squaredNums = squareValues(nums);
-
- squaredNums.subscribe(x => console.log(x));
-
- // Logs
- // 1
- // 4
- // 9
パイプ
パイプを使用するとオペレーターをリンクすることができます。パイプを使用すると、複数の機能を1つの機能にまとめることができます。pipe() 関数は、結合する関数を引数としてとり、実行時に順次関数を実行する新しい関数を返します。
observable に適用される�オペレーターのセットは、レシピ、つまり関心のある値を生成するための一連の命令です。それだけではレシピは何もしません。レシピを通して結果を出すには subscribe() を呼び出す必要があります。
単独利用
- import { filter, map } from 'rxjs/operators';
-
- const nums = of(1, 2, 3, 4, 5);
-
- // Observable を受け入れる関数の生成
- const squareOddVals = pipe(
- filter((n: number) => n % 2 !== 0),
- map(n => n * n)
- );
-
- // filter と map 関数を実行する Observable を生成
- const squareOdd = squareOddVals(nums);
-
- // 結合された関数の実行を購読
- squareOdd.subscribe(x => console.log(x));
Observable.pip
pipe() 関数は RxJS Observable のメソッドでもあるため、短く書き換え
- import { filter, map } from 'rxjs/operators';
-
- const squareOdd = of(1, 2, 3, 4, 5)
- .pipe(
- filter(n => n % 2 !== 0),
- map(n => n * n)
- );
-
- squareOdd.subscribe(x => console.log(x));
コンポーネントからサービスのデータを購読する
- import { Subject } from 'rxjs/subject';
- import { User } from './user';
-
- @Injectable()
- export class AccountService {
- private userChangeAnnouncedSource = new Subject<User>();
- userChangeAnnounced$ = this.userChangeAnnouncedSource.asObservable();
- :
- announceUserChange(user: User) {
- this.userChangeAnnouncedSource.next(user);
- }
- :
Component
- import { Subscription } from 'rxjs/Subscription';
-
- export class AccountComponent implements OnInit, OnDestroy {
- user: User;
- subscription: Subscription
-
- ngOnInit() {
- this.subscription = this.accountService.userChangeAnnounced$.subscribe((user:User) => {
- this.user = user;
- });
- }
-
- ngOnDestroy() {
- this.subscription.unsubscribe();
- }
- :
DI
依存関係を @Optional として @Host で検索を制限
- コンポーネントが依存関係を要求すると、Angularはそのコンポーネントのインジェクターから開始し、 最初の適切なプロバイダーが見つかるまでインジェクターツリーを検索
- @Optional プロパティデコレーターは、依存関係が見つからない場合にnullを返す
- @Host プロパティデコレーターは、上方向への検索を ホストコンポーネント で停止==
@Inject を使用してカスタムプロバイダーを設定
- カスタムプロバイダーを使用すると、組み込みのブラウザAPIなど、暗黙的な依存関係に対する具体的な実装を提供できる
コンポーネントの DOM 要素を注入
プロバイダーを定
- 値プロバイダー: useValue
- クラスプロバイダー: useClass
- エイリアスプロバイダー: useExisting
- ファクトリープロバイダー: useFactory
UI
レスポンシブレイアウト
テスト
ユニットテスト
Karma
Firestoreの利用
機能
Chrome拡張機能
augury
Facebook SDK
Hello.js 認証をまとめるJavaScriptライブラリ
文法
- declare const hoge;
コード
コードからルーティング
- import { Router } from '@angular/router';
- :
- constructor(private router: Router) {}
- :
- this.router.navigate(['/hoge'])
CSRF
CORS対応
参照
Firebase