大田区から発信するゆるゆる日記

主にITエンジニアに関する備忘録日記。たまに趣味も。何か不備があればコメント頂けると幸いです。Twitterアカウント https://twitter.com/ryuzan03

【Angular】Excelやスプレッドシートのような表を作ってみた⑥【テキスト修正時のフォント色変更(クラス付与)編】

※下記の内容に不備がありましたら、コメント頂けると幸いです。また、下記の内容をご使用頂ける場合は自己責任でお願いします。

【目次】

 

概要

この度、作りたかった表が完成したので、その作業内容を数回に分けて記事にしていきます。

Excelスプレッドシートの足元にも及びません←

 

今回はその記事のラスト(第6回目)です。

 

少し複雑なデータ構造をループで表示させて、さらにそのデータを個別に変更する処理の方法を知りたい方にオススメの記事です。

 

第1回 mat-table編

第2回 mat-icon編

第3回 デザイン修正編

第4回 mat-button-toggle-group編

第5回 要素(div/input)切り替え(スタイルバインディング)編

・第6回 テキスト修正時のフォント色変更(クラス付与)編

 

完成形

Excel スプレッドシート

 

実装した機能(?)紹介

・ネストがあるデータを表形式で表示

・mat-icon使用

・表1列目固定

・横スクロール

・リスト表示切り替え

・要素(div/input)の切り替え

・テキスト修正後、クラス追加(赤字切り替え)

 

 

テキスト修正時のフォント色変更(クラス付与)編

テーマ

今回はテキストを修正した時に、フォント色を赤に変更させます。

classlist add

 

前提

前回記事の続きになります。

URL

 

型定義は省いています。

 

データ構成です。

data = { column: [ "Camera", "Name", "Gender", "Hobby" ],
left_column: [ "FirstName", "Hobby2"],
right_column: [ "LastName", "Hobby3"],
person: [{
info: { info1: "loud", info2: "big" },
details: { 'ユニークキー':"abc1", Name: "Taro", Gender: "1", Hobby: "", FirstName: "Taro", LastName: "Tanaka", Hobby2: "", Hobby3: "" }
},
{
info: { info1: "", info2: "" },
details: { 'ユニークキー':"abc2", Name: "Hanako", Gender: "2", Hobby: "", FirstName: "Hanako", LastName: "Yamada", Hobby2: "", Hobby3: "" }
}]
}

 

コード 

component.html

<div class="person-table">
・・・・・・
+ <input type='text'
class="{{person['ユニークキー'] + column}}"
[(ngModel)]='person[column]'
[style.display]="isVisible[person['ユニークキー'] + column] ? 'inline-block' : 'none'"
(blur)="toggleVisible(person['ユニークキー'], column)"
(change)="addFontRedClass(person['ユニークキー'], column)"
>

+ <div class="{{person['ユニークキー'] + column}}"
[style.display]="!isVisible[person['ユニークキー'] + column] ? 'block' : 'none'"
(dblclick)="toggleVisible(person['ユニークキー'], column)"
>
・・・・・・
</div>

<div class="right-person-table">
・・・・・・
+ <input type='text'
class="{{person['ユニークキー'] + column}}"
[(ngModel)]='person[column]'
[style.display]="isVisible[person['ユニークキー'] + column] ? 'inline-block' : 'none'"
(blur)="toggleVisible(person['ユニークキー'], column)"
(change)="addFontRedClass(person['ユニークキー'], column)"
>

+ <div class="{{person['ユニークキー'] + column}}"
[style.display]="!isVisible[person['ユニークキー'] + column] ? 'block' : 'none'"
(dblclick)="toggleVisible(person['ユニークキー'], column)"
>
・・・・・・
</div>

 

component.ts

+ import { DOCUMENT } from '@angular/common';

export class PersonComponent implements OnInit {

・・・・・・・・・・

+ constructor(@Inject(DOCUMENT) private document: any) { }

ngOnInit() {

・・・・・・・・・・

+ addFontRedClass(uniqueKey, column) {
+ const className = uniqueKey + column;

+ const inputClass = 'input[class^="' + className + '"]';
+ const inputEl = this.document.querySelector(inputClass);
+ if (inputEl) {
+ inputEl.classList.add('change-data');
+ }

+ const divClass = 'div[class*="' + className + '"]';
+ const divEl = this.document.querySelector(divClass);
+ if (divEl) {
+ divEl.classList.add('change-data');
+ }
+ }

}

 

component.scss

.change-data {
color: red;
}

 

ポイント

物凄く見にくくてすみません。。。

 

今回は特にポイントはありません。要素を指定してあげて、クラスを付与するだけです。

 

逆にquerySelectorメソッドを使うのが正解なのか不安・・・

Elementを探さずに、classを付与する方法がありそう。

 

 

今後に向けて 

この表を作るのに、自分は1ヶ月程かかりました。上司は1週間程で作れるとのこと。

 

しかし、こうやって冷静にまとめてみると、1日でもできそうな気がします。

無知ゆえの仕事の遅さですね。

 

日頃から勉強して、いついかなる時でも大体の仕様が頭に思い浮かぶようになりたいものです。できれば、さらにその場でアウトプットできるようになりたいです。

【Angular】Excelやスプレッドシートのような表を作ってみた⑤【要素(div/input)切り替え(スタイルバインディング)編】

※下記の内容に不備がありましたら、コメント頂けると幸いです。また、下記の内容をご使用頂ける場合は自己責任でお願いします。

【目次】

 

概要

この度、作りたかった表が完成したので、その作業内容を数回に分けて記事にしていきます。

Excelスプレッドシートの足元にも及びません←

 

今回はその記事の第5回目です。

 

少し複雑なデータ構造をループで表示させて、さらにそのデータを個別に変更する処理の方法を知りたい方にオススメの記事です。

 

第1回 mat-table編

第2回 mat-icon編

第3回 デザイン修正編

第4回 mat-button-toggle-group編

・第5回 要素(div/input)切り替え(スタイルバインディング)編

第6回 テキスト修正時のフォント色変更(クラス付与)編

 

完成形

Excel スプレッドシート

 

実装した機能(?)紹介

・ネストがあるデータを表形式で表示

・mat-icon使用

・表1列目固定

・横スクロール

・リスト表示切り替え

・要素(div/input)の切り替え

・テキスト修正後、クラス追加(赤字切り替え)

 

 

要素(div/input)切り替え(スタイルバインディング)編

テーマ

今回はdiv要素とinput要素の表示をスタイルバインディングを使って切り替えていきたいと思います。

display バインディング

 

前提

前回記事の続きになります。

URL

 

型定義は省いています。

 

データ構成です。

今回はデータにユニークキーを増やしています。

data = { column: [ "Camera", "Name", "Gender", "Hobby" ],
left_column: [ "FirstName", "Hobby2"],
right_column: [ "LastName", "Hobby3"],
person: [{
info: { info1: "loud", info2: "big" },
+ details: { "ユニークキー":"abc1", Name: "Taro", Gender: "1", Hobby: "", FirstName: "Taro", LastName: "Tanaka", Hobby2: "", Hobby3: "" }
},
{
+ info: { info1: "", info2: "" },
details: { "ユニークキー":"abc2", Name: "Hanako", Gender: "2", Hobby: "", FirstName: "Hanako", LastName: "Yamada", Hobby2: "", Hobby3: "" }
}]
}

 

なぜindexを使わない?

同じ列名を表示させるテーブルをいくつも表示させる場合に対応させるためです。列名とindexだけでデータを探しても、一意にはならないため複数のデータが見つかってしまいます。

 

person毎にユニークキーを設定しておけば、列名とユニークキーでデータを探すことができるので、indexを使いませんでした。

 

なぜngIfディレクティブを使わない?

今回の備忘録シリーズの中では詳しく触れていないのですが、描画時に前回修正があった場合もテキストを赤字に変更する機能を付けています。

 

テキストを赤字に変更する流れは、

DBからデータ取得→修正の有無確認→修正があった場合はクラス付与

になります。

 

しかし、ngIfディレクティブは要素自体を表示させないため、上記のクラス付与において最初は非表示にさせているinput要素を検索することができず、クラス付与ができなくなるので、今回はngIfディレクティブを使用していません。

 

コード

component.html

<div class="person-table">
・・・・・・
+ <input type='text' [(ngModel)]='person[column]' [style.display]="isVisible[person['ユニークキー'] + column] ? 'inline-block' : 'none'" (blur)="toggleVisible(person['ユニークキー'], column)">
+ <div [style.display]="!isVisible[person['ユニークキー'] + column] ? 'block' : 'none'" (dblclick)="toggleVisible(person['ユニークキー'], column)">
+ {{ person[column] }}
+ </div>
・・・・・・
</div>

<div class="right-person-table">
・・・・・・
+ <input type='text' [(ngModel)]='person[column]' [style.display]="isVisible[person['ユニークキー'] + column] ? 'inline-block' : 'none'" (blur)="toggleVisible(person['ユニークキー'], column)">
+ <div [style.display]="!isVisible[person['ユニークキー'] + column] ? 'block' : 'none'" (dblclick)="toggleVisible(person['ユニークキー'], column)>
+ {{ person[column] }}
+ </div>
・・・・・・
</div>

 

component.ts

+ import { Component, OnInit } from '@angular/core';

export class PersonComponent implements OnInit {

+ isVisible: {};

・・・・・・・・・・

+ ngOnInit() {
+ const value = this.data.person.map(p => {
+ const uniqueKey = p.details['ユニークキー'];
+ Object.keys(p.details).map(column => {
+ const isVisibleKey = uniqueKey + column;
+ this.isVisible = { [isVisibleKey]: false };
+ })
+ });
+ }

・・・・・・・・・・

+ toggleVisible(uniqueKey, column) {
+ const isVisibleKey = uniqueKey + column;
+ this.isVisible = {
+ [isVisibleKey]: !this.isVisible[isVisibleKey]
+ };
+ }

}

 

ポイント

ポイントはpersonのユニークキーとカラム名で作ったKeyとtrue/false判定ができるValueを持ったオブジェクト(isVisible)を作ることです。

 

html側でisVisbleの変更を感知(スタイルバインディング)し、要素(div/input)の表示の切り替えを行ってくれます。

 

また、今回はデータの修正を同時に複数を行わない仕様です。なので、isVisibleオブジェクトで全てのデータの真偽値判定をするプロパティを持っておく必要はなく、データを上書きしていく仕様で問題ありません。

 

 

今後に向けて

次回がラストです。

テキストを修正した時に、クラスを付与してテキストを赤くする機能を実装していきます。

 

 

参考

素晴らしい記事に感謝いたします。

Angular Material UI component library(mat-table)

Angular Material UI component library(mat-button-toggle)

【Angular】Excelやスプレッドシートのような表を作ってみた④【mat-button-toggle-group編】

※下記の内容に不備がありましたら、コメント頂けると幸いです。また、下記の内容をご使用頂ける場合は自己責任でお願いします。

【目次】

 

概要

この度、作りたかった表が完成したので、その作業内容を数回に分けて記事にしていきます。

Excelスプレッドシートの足元にも及びません←

 

今回はその記事の第4回目です。

 

少し複雑なデータ構造をループで表示させて、さらにそのデータを個別に変更する処理の方法を知りたい方にオススメの記事です。

 

第1回 mat-table編

第2回 mat-icon編

第3回 デザイン修正編

・第4回 mat-button-toggle-group編

第5回 要素(div/input)切り替え(スタイルバインディング)編

第6回 テキスト修正時のフォント色変更(クラス付与)編

 

完成形

Excel スプレッドシート

実装した機能(?)紹介

・ネストがあるデータを表形式で表示

・mat-icon使用

・表1列目固定

・横スクロール

・リスト表示切り替え

・要素(div/input)の切り替え

・テキスト修正後、クラス追加(赤字切り替え)

 

  

mat-button-toggle-group編

テーマ

今回はmat-button-toggle-groupを使って、リスト表示の切り替え機能を実装していきます。

コード量が一気に多くなります。

mat-button-toggle-group

 

前提

前回記事の続きになります。

URL

 

型定義は省いています。

 

データ構成です。

今回はcolumnの種類を増やしています。

※雑なcolumnの追加と見にくさはお許しくださいmm

 data = { column: [ "Camera", "Name", "Gender", "Hobby" ],
+ left_column: [ "FirstName", "Hobby2"],
+ right_column: [ "LastName", "Hobby3"],
person: [{
info: { info1: "loud", info2: "big" },
+ details: { Name: "Taro", Gender: "1", Hobby: "", FirstName: "Taro", LastName: "Tanaka", Hobby2: "", Hobby3: "" }
},
{
info: { info1: "", info2: "" },
+ details: { Name: "Hanako", Gender: "2", Hobby: "", FirstName: "Hanako", LastName: "Yamada", Hobby2: "", Hobby3: "" }
}]
}

 

コード

module.ts

+ import { MatButtonToggleModule } from '@angular/material/button-toggle';

・・・・・・・・・

imports: [
+ MatButtonToggleModule
],

・・・・・・・・・

  

component.html

+ <div class="contents">
+ <mat-button-toggle-group #group="matButtonToggleGroup">
+ <mat-button-toggle value="left_column" checked="true" aria-label="Text align left" class="product-button">
+ <mat-icon class="product-icon">ああ</mat-icon>
+ </mat-button-toggle>
+ <mat-button-toggle value="right_column" aria-label="Text align right" class="product-button">
+ <mat-icon class="product-icon">あああ</mat-icon>
+ </mat-button-toggle>
+ </mat-button-toggle-group>
+ </div>

<div class="person-table">
・・・・・・
</div>

+ <div class="right-person-table">
+ <mat-table [dataSource]="getData(data)">
+ <ng-container *ngFor="let column of data[group.value]">
+ <ng-container [matColumnDef]="column">
+ <th mat-header-cell *matHeaderCellDef>{{ column }}</th>
+ <td mat-cell *matCellDef="let person">
+ <input type='text' [(ngModel)]='person[column]'>
+ </td>
+ </ng-container>
+ </ng-container>
+ <tr mat-header-row *matHeaderRowDef="data[group.value]"></tr>
+ <tr mat-row *matRowDef="let row; columns: data[group.value];"></tr>
+ </mat-table>
+ </div>

 

ポイント

ポイントは以下の3つです。

 

・mat-button-toggle要素のvalue属性に、表示させるリストの列名が入っている配列オブジェクトのキー(今回はleft_columnとright_column)を指定する

・mat-button-toggle-group要素で定義したローカル変数(group)を利用し、mat-header-row要素とmat-row要素に上記のキーを代入する

・描画時に出しておきたいリストが決まっている場合は、そのリストのキーを定義しているmat-button-toggle要素に「checked="true"」を追加する

 

 

今後に向けて

次回は要素(div/input)の切り替えを行います。

通常はindexを使うと思いますが、複数テーブルを作成してindexだけでは切り替える要素の指定ができない場合の要素切り替えを行います。

 

 

参考

素晴らしい記事に感謝いたします。

Angular Material UI component library(mat-table)

Angular Material UI component library(mat-button-toggle)

【Angular】Excelやスプレッドシートのような表を作ってみた③【デザイン修正編】

※下記の内容に不備がありましたら、コメント頂けると幸いです。また、下記の内容をご使用頂ける場合は自己責任でお願いします。

【目次】

 

概要

この度、作りたかった表が完成したので、その作業内容を数回に分けて記事にしていきます。

Excelスプレッドシートの足元にも及びません←

 

今回はその記事の第3回目です。

 

少し複雑なデータ構造をループで表示させて、さらにそのデータを個別に変更する処理の方法を知りたい方にオススメの記事です。

 

第1回 mat-table編

第2回 mat-icon編

・第3回 デザイン修正編

第4回 mat-button-toggle-group編

第5回 要素(div/input)切り替え(スタイルバインディング)編

第6回 テキスト修正時のフォント色変更(クラス付与)編

 

完成形

Excel スプレッドシート

 

実装した機能(?)紹介

・ネストがあるデータを表形式で表示

・mat-icon使用

・表1列目固定

・横スクロール

・リスト表示切り替え

・要素(div/input)の切り替え

・テキスト修正後、クラス追加(赤字切り替え)

 

  

デザイン修正編

テーマ

今回は簡単なデザイン修正を行います。

具体的には、1列目を固定したり、横スクロールができるようにしていきます。

 

実は、1列目の固定はmat-tableにstickyと付け加えるだけ実装できます。しかし、私の場合はそれが上手く効かなかったので、自力で実装することになりました。

 

細かいデザイン(交互に色を変える・テキストを中央表示させるなど)については本記事には書いておりませんので、詳細についてはグーグルさんに聞いてみてください。

sticky

 

前提

前回記事の続きになります。

ryuzan03.hatenablog.com

 

型定義は省いています。

 

コード

component.html

+ <div class="person-table">
<mat-table [dataSource]="getData(data)">
<ng-container *ngFor="let column of data['column']; let i = index">

<ng-container *ngIf="i === 0; else elseColumn">
<ng-container [matColumnDef]="column">
<th mat-header-cell *matHeaderCellDef>画像表示</th>
<td mat-cell *matCellDef="let person">
<mat-icon svgIcon="camera-icon">
</td>
</ng-container>
</ng-container>

<ng-template #elseColumn>
<ng-container [matColumnDef]="column">
<th mat-header-cell *matHeaderCellDef>{{ column }}</th>
<td mat-cell *matCellDef="let person">
<input type='text' [(ngModel)]='person[column]'>
</td>
</ng-container>
</ng-template>

</ng-container>

<tr mat-header-row *matHeaderRowDef="data['column']"></tr>
<tr mat-row *matRowDef="let row; columns: data['column'];"></tr>
</mat-table>
+ </div>

 

component.scss

.person-table {
overflow: auto;
}

mat-table {
width: fit-content;
}

.mat-column-cameraColumn {
position: sticky;
left: 0;
}

 

ポイント

ポイントはmat-tableのwidthに「fit-content」を追加することです。

こうしておかないと、固定列がブラウザ画面に表示されているtable内でしか固定されず、ブラウザ画面に表示されていない部分がスクロールされてくると動いてしまいます。

 

 

 

今後に向けて

次回はmat-button-toggle-groupを使って、カラムの表示を切り替えていきたいと思います。

 

 

参考

素晴らしい記事に感謝いたします。

Angular Material UI component library

【Angular】Excelやスプレッドシートのような表を作ってみた②【mat-icon編】

※下記の内容に不備がありましたら、コメント頂けると幸いです。また、下記の内容をご使用頂ける場合は自己責任でお願いします。

【目次】

 

概要

この度、作りたかった表が完成したので、その作業内容を数回に分けて記事にしていきます。

Excelスプレッドシートの足元にも及びません←

 

今回はその記事の第2回目です。

 

少し複雑なデータ構造をループで表示させて、さらにそのデータを個別に変更する処理の方法を知りたい方にオススメの記事です。

 

第1回 mat-table編

・第2回 mat-icon編

第3回 デザイン修正編

第4回 mat-button-toggle-group編

第5回 要素(div/input)切り替え(スタイルバインディング)編

第6回 テキスト修正時のフォント色変更(クラス付与)編

 

完成形

Excel スプレッドシート

 

実装した機能(?)紹介

・ネストがあるデータを表形式で表示

・mat-icon使用

・表1列目固定

・横スクロール

・リスト表示切り替え

・要素(div/input)の切り替え

・テキスト修正後、クラス追加(赤字切り替え)

 

  

mat-icon編

テーマ

今回はmat-iconの実装を行います。

mat-icon

 

前提

前回記事の続きになります。

ryuzan03.hatenablog.com

 

型定義は省いています。

 

データ構成です。

今回はcolumn配列データの最初に「Camera」を追加します。

※見にくくてすみませんmm

+ data = { column: [ "Camera", "Name", "Gender", "Hobby" ] ,
person: [{
info: { info1: "loud", info2: "big" },
details: { Name: "Taro", Gender: "1", Hobby: "" }
},
{
info: { info1: "", info2: "" },
details: { Name: "Hanako", Gender: "2", Hobby: "" }
}]
}

 

コード

module.ts

+ import { MatIconModule } from '@angular/material/icon';

・・・・・・・・・

+ imports: [ MatIconModule ],

・・・・・・・・・

 

component.ts 

+ import { DomSanitizer } from '@angular/platform-browser';
+ import { MatIconRegistry } from '@angular/material';

・・・・・・・・・

constructor(
+ private matIconRegistry: MatIconRegistry,
+ private domSanitizer: DomSanitizer
) {
+ this.matIconRegistry.addSvgIcon(
+ 'camera-icon',
+ this.domSanitizer.bypassSecurityTrustResourceUrl('dist/assets/camera_alt-24px.svg')
) ///アイコンダウンロードはこちらから
}

・・・・・・・・・

 

component.html

<mat-table [dataSource]="getData(data)">
+ <ng-container *ngFor="let column of data['column']; let i = index">

+ <ng-container *ngIf="i === 0; else elseColumn">
+ <ng-container [matColumnDef]="column">
+ <th mat-header-cell *matHeaderCellDef>画像表示</th>
+ <td mat-cell *matCellDef="let person">
+ <mat-icon svgIcon="camera-icon">
+ </td>
+ </ng-container>
+ </ng-container>

+ <ng-template #elseColumn>
<ng-container [matColumnDef]="column">
<th mat-header-cell *matHeaderCellDef>{{ column }}</th>
<td mat-cell *matCellDef="let person">
<input type='text' [(ngModel)]='person[column]'>
</td>
</ng-container>
+ </ng-template>

</ng-container>

<tr mat-header-row *matHeaderRowDef="data['column']"></tr>
<tr mat-row *matRowDef="let row; columns: data['column'];"></tr>
</mat-table>

 

ポイント

ポイントは以下の4つです。

 

・Column配列データの最初の値に「Camera」を追加する

・assetsファイルにsvgデータを格納する

DomSanitizerサニタイズを回避する

・ifとindexを利用して、列を「indexが0の列」と「それ以外の列」に分ける

・indexが0の列にmat-icon要素を追加し、コンポーネントで指定した「camera-icon」を挿入する

 

アイコンのsvgデータはこちらから入手可能です。
Icons - Material Design

 

 

今後に向けて

次回は少しデザインを整えていきます。

 

 

参考

素晴らしい記事に感謝いたします。

Angular Material UI component library

Icons - Material Design

https://angular.jp/api/platform-browser/DomSanitizer

Angular Materialで<mat-icon>を使う - Qiita

【Angular】Excelやスプレッドシートのような表を作ってみた①【mat-table編】

※下記の内容に不備がありましたら、コメント頂けると幸いです。また、下記の内容をご使用頂ける場合は自己責任でお願いします。

【目次】

 

概要

以前にmat-tableを使ってネストがあるデータを表示させる方法について記事にしました。

【Angular/Material】ネストがある配列データをmat-tableで表示させる - 大田区から発信するゆるゆる日記

 

上記の記事を書いていた時に実はある機能を作っていました。それは、データをブラウザに表形式で表示させ、さらにそのデータを修正できる機能です。上記の記事はその中で学んだ知識の備忘録でした。

 

そして、この度その表が完成しました!せっかくなので、その作業内容を数回に分けて記事にしていこうと思います。

Excelスプレッドシートの足元にも及びません←

 

少し複雑な構造のデータをループで表示させ、さらにそのデータを個別で変更できる機能を作りたい方にオススメの記事です(基本的なことをしているだけかもしれませんが・・・)

 

・第1回 mat-table編

第2回 mat-icon編

第3回 デザイン修正編

第4回 mat-button-toggle-group編

第5回 要素(div/input)切り替え(スタイルバインディング)編

第6回 テキスト修正時のフォント色変更(クラス付与)編

 

実装した機能(?)紹介

・ネストがあるデータを表形式で表示

・mat-icon使用

・表1列目固定

・横スクロール

・リスト表示切り替え

・要素(div/input)の切り替え

・テキスト修正後、クラス追加(赤字切り替え)

 

完成画像

はてブは動画貼れないんですね...

 

完成形

Excel スプレッドシート

 

 

横スクロール

mat-table

 

 

リスト切り替え(右上上部バーにより右下リストの表示内容切り替え)

mat-button-toggle

 


要素の切り替え(div⇆input)

display

 

 

テキスト修正後、赤字に切り替え

classlist add

 

classlist add

 

 

mat-table編

テーマ

今回はmat-tableの実装を行います。

 

前提

mat-table編は前回書いた記事から基本的な内容を省いた記事です。より詳しい内容を知りたい場合は、前回記事を参考にしてみてください。

【Angular/Material】ネストがある配列データをmat-tableで表示させる - 大田区から発信するゆるゆる日記

 

型定義は省いています。

 

データ構成です。

※見にくくてすみませんmm

 data = { column: [ "Name", "Gender", "Hobby" ] ,
person: [{
info: { info1: "loud", info2: "big" },
details: { Name: "Taro", Gender: "1", Hobby: "" }
},
{
info: { info1: "", info2: "" },
details: { Name: "Hanako", Gender: "2", Hobby: "" }
}]
}

 

コード

component.html

<mat-table [dataSource]="getData(data)">
<ng-container *ngFor="let column of data['column']">
<ng-container [matColumnDef]="column">
<th mat-header-cell *matHeaderCellDef>{{ column }}</th>
<td mat-cell *matCellDef="let person">
<input type='text' [(ngModel)]='person[column]'>
</td>
</ng-container>
</ng-container>

<tr mat-header-row *matHeaderRowDef="data['column']"></tr>
<tr mat-row *matRowDef="let row; columns: data['column'];"></tr>
</mat-table>

component.ts 

getData(data) {
const value = data.person.map(p => {
return p.details;
});
return value;
}

  

ポイント

ポイントはdataSource属性に指定しているgetDataメソッドです。getDataメソッドでcolumn配列をKeyとするオブジェクトデータを取得しています。もちろん、このオブジェクトデータをあらかじめcomponentの変数に格納しておき、html側で変数だけを指定するのもokです。

 

 

今後に向けて

次回はmat-table内でmat-iconを使う方法を書いていきます。

 

 

参考

素晴らしい記事に感謝いたします。

Angular Material UI component library

【Angular】ngModelChangeイベントとchangeイベントの比較

※下記の内容に不備がありましたら、コメント頂けると幸いです。また、下記の内容をご使用頂ける場合は自己責任でお願いします。

【目次】

 

概要

ngModelChangeイベントとchangeイベントの違いについてまとめていきます。

 

ngModelChangeイベントとchangeイベントの比較

ngModelChangeイベント

Angular

ngModelChangeイベントはngModelディレクティブの@Outputです。

つまり、ngModelディレクティブがないと使うことができませんし、$eventには値が変わったvalueのみが格納されます。

 

 

使い方

component.html

 <input type="text" [(ngModel)]="name" (ngModelChange)="console.log($event)">

※consoleをテンプレートで使うには、コンポーネントでconsoleメソッドを変数に代入しておく必要があります

 

この状態でinput内のtextを変更すると、変更する度にngModelChangeイベントが発火します。

例えば、nameに「あいうえお」が代入されていた場合、「あいうえお」を「お」から「あ」の順番に削除していくと、下記のような挙動になります。

 

Console  

あいうえ // 「お」削除
あいう // 「え」削除
あい // 「う」削除
あ // 「い」削除
// 「あ」削除

 

 

changeイベント

HTMLElement: change イベント - Web API | MDN

changeイベントは要素の値の変更が確定した時に発生します。

input要素を抽出したい時は「$event.target」、valueプロパティ値を抽出したい時は「$value.target.value」などを使用します。

 

 

使い方

component.html

 <input type="text" [(ngModel)]="name" (change)="console.log($event.target, $event.target.value)">

※consoleをテンプレートで使うには、コンポーネントでconsoleメソッドを変数に代入しておく必要があります

 

今回はconsole.logの引数を二つにしています。

 

この状態でinput内のtextを変更すると、変更が確定した時にのみchangeイベントが発火します。

例えば、nameに「あいうえお」が代入されていた場合、「あいうえお」を「お」から「う」まで削除してEnterもしくはinput要素から離れると、下記のような挙動になります。

 

Console  

<input type="text" ng-reflect-mode="あいう" class="ng-untouched ng-valid ng-dirty"> "あいう" // 「おう」削除後にEnterもしくはinput要素から離れる

 

 

比較

発火タイミング

ngModelChangeイベント

⇨ngModelが変更される度に発火

 

changeイベント

⇨要素の値の変更が確定した時に発火

 

$eventに格納されている値

ngModelChangeイベント

⇨変更されたvalueのプロパティ値

 

changeイベント

⇨発生したイベントに関わる様々な情報(プロパティ)やメソッド=イベントオブジェクト

 

 

今後に向けて

もっとレベルの高い記事を書きたい。

 

参考

素晴らしい記事に感謝いたします。

Angular

HTMLElement: change イベント - Web API | MDN

javascript - (change) vs (ngModelChange) in angular - Stack Overflow