LoginSignup
3
3

More than 5 years have passed since last update.

angular material componentsの使用

Last updated at Posted at 2018-12-18

angular materialを使用して簡単なプログラムを作成してみました。都道府県のリストデータをCRUDするプログラムの作例です。殆どがAngular MaterialのExampleベースのコードですが、自分の思うよう動作をさせるにあたり、調査・コーディングした部分も有るのでブログに載せてみます。
※DB連動していないため、追加変更したデータは保持されません。
image.png

上記のテーブルに加え、ダイアログボックスを実装してみます。
image.png

Angular MaterialのStart upに従いプロジェクトを作成し、各コンポーネントの利用方法はExampleを参考にしています。ソースはstackblitzにアップしてあり、動作確認可能です。

環境

Angular CLI: 7.0.7
Node: 8.11.4
OS: windows8.1 x64
Angular: 7.0.4

Package Version
@angular-devkit/core 7.0.7
@angular-devkit/schematics 7.0.7
@angular/cdk 7.1.1
@angular/cli 7.0.7
@angular/material 7.1.1
@ngtools/webpack 7.0.7
@schematics/angular 7.0.7
@schematics/update 0.10.7
rxjs 6.3.3
typescript 3.1.6
webpack 4.19.1

使用したmaterialコンポーネントは以下です。

BrowserAnimationsModule
MatInputModule
MatButtonModule
MatTableModule
MatCheckboxModule
MatDialogModule
MatPaginatorModule
MatSortModule
MatSelectModule

アプリケーションコンポーネント

コンポーネント/サービス 説明 material
PrefViewComponent table表示,選択,フィルター,ソート,ページング MatTableModule,MatCheckboxModule,MatPaginatorModule,MatSortModule,MatSelectModule
PrefViewEditComponent 編集ボタン,Dialog呼出,データ削除 MatButtonModule,MatDialogModule
PrefViewEditDialogComponent Dialog表示,データ追加・更新 MatDialogModule,MatInputModule,MatButtonModule
prefService データ保持,コンポーネント連携

以下アプリケーションコンポーネントのポイント部分のみ、抜粋して説明します。

PrefViewComponent

単一行選択の実装

matCheckBoxがバインドしているSelectionModelの生成にて、コンストラクタ第一引数(選択モード指定)に単一(false)を指定します。

pref-view.component.ts
  selection = new SelectionModel<PrefItem>(false,[]);

checkBox変更のイベントをリスニングするため、同SelectionModelのエミッターを宣言してsubscribeにコールバック関数を設定します。

pref-view.component.ts
  private cbEmmiter=this.selection.onChange.asObservable();

  ngOnInit() {
    this.cbEmmiter.subscribe(cb=>{
      if(cb.source.selected.length > 0){
        this.service.selectPerfItem=cb.source.selected[0];
      }else{
        this.service.selectPerfItem=null;
      }
    });
  }
列ソート ページング

MatSort, MatPaginatorを使用することで簡単に実装できます。実装方法はExampleの通りです。作例ではtableのdatasourceが非同期に更新されるので、その契機で同コンポーネントを再バインドする必要があります。該当の処理をngAfterViewInitに書きます。

pref-view.component.ts

  ngAfterViewInit(){
    this.dataSource.paginator = this.paginator;
    this.dataSource.sort = this.sort;
  }

また、datasourceバインドの契機にも同処理を書いておきます。

pref-view.component.ts
  updateData(){
    //tableのデータソース更新
    this.dataSource= new MatTableDataSource<PrefItem>(this.service.data);
    this.dataSource.paginator = this.paginator;
    this.dataSource.sort = this.sort;
  }
フィルター

Exampleをそのまま流用です。MatTableDataSourceのfilterメソッドを使用しています。

PrefViewEditDialogComponent

親コンポーネントと切り離れた方が可読性が良いと思い、独立コンポーネントとして実装ました。これにより1つのコンポーネントに縛られることなく、複数のコンポーネントで共有することができます。サービスから動作モードを取得して、追加・更新ダイアログを共通にしています。
MatInputの数値表示をカンマ区切りとしたいため、changeイベントで変換をかけています。

pref-edit-dialog.component.ts
   onChangeArea(){
    this.editItem$.prefArea=Number(this.perfArea$.replace(/,/g,''));
    this.perfArea$=formatNumber(this.editItem$.prefArea,this.locale,'.2');
  }

Dialog上でデータの追加・更新を処理しており、処理後の通知をサービスのObservableに流しています。他コンポーネントはサービスのObservableをsubscribeすることで変更通知を受信することができます。この仕組みによってtableコンポーネントは表示を更新します。

最後に

materialを使ってみた感触ですが、あまり突っかかることなく使えました(気持ち良く使える)。特に気に入っているところはDialogの使いやすさです。コンポーネント化すれば、どのコンポーネントからも呼べるし、別途作成したコンポーネントをDialog上に配置することもできます。疎結合デザインのメリットを実感できるUIですね。

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