【Angular】Mat-tableの列データを編集・追加・削除する

この記事は約13分で読めます。

 

 

今回はAngularのmat-tableに編集ボタンを付けて、編集ボタンからダイアログを開くとダイアログが開き、フォームに入力した情報がテーブルに反映される、というような機能を実装していきたいと思います。

 

MattableとMatDialogの導入方法については以下の記事で解説しているので、まずそちらを参考にしてください。

 

 

【Angular】ダイアログ画面をMat-dialogで実装する

AngularによるWebアプリ開発⑧~Mat-Tableでテーブルを作成する

 

 

# コンポーネントを作成する
$ ng generate component edit-table-sample
$ ng generate component edit-dialog

 

 

<app-routing.module.ts>

import { NgModule } from "@angular/core";
import { Routes, RouterModule } from "@angular/router";
~~~~
~~~~
import { EditTableSampleComponent } from "./edit-table-sample/edit-table-sample.component"; //これを追加する!

const routes: Routes = [

  { path: "edit-mattable-sample", component: EditTableSampleComponent }, //これを追加!
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
})
export class AppRoutingModule {}

 

 

import { BrowserModule } from "@angular/platform-browser";
import { NgModule } from "@angular/core";
import { AppRoutingModule } from "./app-routing.module";
import { AppComponent } from "./app.component";
~~~~
~~~~
import { EditTableSampleComponent } from "./edit-table-sample/edit-table-sample.component"; //これを追加
import { EditDialogComponent } from "./edit-dialog/edit-dialog.component"; //これを追加

@NgModule({
  declarations: [
    AppComponent,
    ~~~~
    EditTableSampleComponent, //これを追加
    EditDialogComponent,//これを追加
  ],
  imports: [
  ],
  providers: [],
  entryComponents: [EditDialogComponent],//これを追加
 
})
export class AppModule {}

 

 

<edit-table-sample.component.html>

<div style='padding:20px;'>

<table mat-table [dataSource]="dataSource" #mytable class="my-table mat-elevation-z8">

<!-- Id Column -->
<ng-container matColumnDef="id">
<th mat-header-cell *matHeaderCellDef> ID. </th>
<td mat-cell *matCellDef="let element"> {{element.id}} </td>
</ng-container>

<!-- Name Column -->
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef> 名前 </th>
<td mat-cell *matCellDef="let element"> {{element.name}} </td>
</ng-container>

<!-- Action Column -->
<ng-container matColumnDef="action">
<th mat-header-cell *matHeaderCellDef> アクション </th>
<td mat-cell *matCellDef="let element" class="action-link">
<a (click)="openDialog('更新',element)"><button mat-raised-button color='primary'>編集</button></a>
<a (click)="openDialog('削除',element)"><button mat-raised-button>削除</button></a>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
<br /><br />
<button mat-button (click)="openDialog('Add',{})" mat-flat-button color="primary">列を追加する</button>
</div>

 

 

<edit-table-sample.component.ts>

import { Component, OnInit, ViewChild } from "@angular/core";
import { MatDialog, MatTable } from "@angular/material";
import { EditDialogComponent } from "../edit-dialog/edit-dialog.component";

export interface UsersData {
  name: string;
  id: number;
}

const ELEMENT_DATA: UsersData[] = [
  { id: 1560608769632, name: "Artificial Intelligence" },
  { id: 1560608796014, name: "Machine Learning" },
  { id: 1560608787815, name: "Robotic Process Automation" },
  { id: 1560608805101, name: "Blockchain" },
];
@Component({
  selector: "app-edit-table-sample",
  templateUrl: "./edit-table-sample.component.html",
  styleUrls: ["./edit-table-sample.component.css"],
})
export class EditTableSampleComponent implements OnInit {
  ngOnInit() {}

  displayedColumns: string[] = ["id", "name", "action"];
  dataSource = ELEMENT_DATA;

  @ViewChild(MatTable, { static: true }) table: MatTable;

  constructor(public dialog: MatDialog) {}

  openDialog(action, obj) {
    obj.action = action;
    const dialogRef = this.dialog.open(EditDialogComponent, {
      width: "250px",
      data: obj,
    });

    dialogRef.afterClosed().subscribe((result) => {
      if (result.event == "Add") {
        this.addRowData(result.data);
      } else if (result.event == "更新") {
        this.updateRowData(result.data);
      } else if (result.event == "削除") {
        this.deleteRowData(result.data);
      }
    });
  }

  addRowData(row_obj) {
    var d = new Date();
    this.dataSource.push({
      id: d.getTime(),
      name: row_obj.name,
    });
    this.table.renderRows();
  }
  updateRowData(row_obj) {
    this.dataSource = this.dataSource.filter((value, key) => {
      if (value.id == row_obj.id) {
        value.name = row_obj.name;
      }
      return true;
    });
  }
  deleteRowData(row_obj) {
    this.dataSource = this.dataSource.filter((value, key) => {
      return value.id != row_obj.id;
    });
  }
}

 

 

<edit-dialog.component.ts>

import { Component, OnInit, Inject, Optional } from "@angular/core";
import { MatDialogRef, MAT_DIALOG_DATA } from "@angular/material";

export interface UsersData {
  name: string;
  id: number;
}

@Component({
  selector: "app-edit-dialog",
  templateUrl: "./edit-dialog.component.html",
  styleUrls: ["./edit-dialog.component.css"],
})
export class EditDialogComponent implements OnInit {
  action: string;
  local_data: any;

  constructor(
    public dialogRef: MatDialogRef,
    //@Optional() is used to prevent error if no data is passed
    @Optional() @Inject(MAT_DIALOG_DATA) public data: UsersData
  ) {
    console.log(data);
    this.local_data = { ...data };
    this.action = this.local_data.action;
  }

  doAction() {
    this.dialogRef.close({ event: this.action, data: this.local_data });
  }

  closeDialog() {
    this.dialogRef.close({ event: "Cancel" });
  }

  ngOnInit() {}
}

 

 

<edit-dialog.component.html>

<h1 mat-dialog-title>アクション: <strong>{{action}}</strong></h1>
<div mat-dialog-content>
  <mat-form-field *ngIf="action != 'Delete'; else elseTemplate">
    <input placeholder="{{action}} Name" matInput [(ngModel)]="local_data.name">
  </mat-form-field>
  <ng-template #elseTemplate>
    本当に削除しますか? <b>{{local_data.name}}</b>?
  </ng-template>
</div>
<div mat-dialog-actions>
  <button mat-button (click)="doAction()" mat-flat-button color="primary">{{action}}</button>
  <button mat-button (click)="closeDialog()">キャンセル</button>
</div>

 

 

以上のコードを追記した状態でhttp://localhost:4200/edit-mattable-sampleにアクセスすると以下のような状態になっています。

 

 

 

 

そして、各ボタンをクリックすると以下のようにダイアログが表示されデータを編集・削除することができます。

 

 

 

 

 

【Githubのサンプルコード】

beginerSE/Angular-Demo
ブログ用Angularソースコード集. Contribute to beginerSE/Angular-Demo development by creating an account on GitHub.
beginerSE/Angular-Demo
ブログ用Angularソースコード集. Contribute to beginerSE/Angular-Demo development by creating an account on GitHub.

 

 

参照:https://www.freakyjolly.com/angular-material-table-operations-using-dialog/#.XtFZ52j7THo

 

 

関連記事:【Angular】Mat-Tableでヘッダーが複数行になるテーブルを作ってみる

関連記事:【Angular】Mattableの各ヘッダー列の幅を画面幅に合わせて自動調整する

関連記事:AngularによるWebアプリ開発⑧~Mat-Tableでテーブルを作成する

 

 

 

 

 

 

 

コメント

タイトルとURLをコピーしました