iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 3
0

簡述

SharedModule是共用模塊的集合地,
此篇分兩篇來介紹常見的幾種共用模塊。

功能

後台製作的過程中,有許多功能是複用的。

  • DialogModule
  • MateriaModule
  • PipeModule
  • ValidationModule
  • LoadingModule

實作

(一) DialogModule

此功能模塊是專門放置Dialog

dialog

檔案結構:

-src
  |-app
    |-app.component.css
    |-app.component.html
    |-app.component.ts
    |-app.module.ts
    |-config
        |-errorcode.ts
    |-shared
       |-dialog
            |-alert
                |-dialog-alert.component.css
                |-dialog-alert.component.html
                |-dialog-alert.component.ts
            |-delete
                |-dialog-delete.component.css
                |-dialog-delete.component.html
                |-dialog-delete.component.ts
            |-dialog.module.ts
       |-shared.module.ts

實務上很常被運用在有錯誤訊息的時候,
或是要 showerrorcode方便知道成功或失敗。

--

errorcode.ts

/*
  name matcher i18n
*/
export const ErrorCodeMsg = [
  { name: "err_access", code: 0 }, //成功
  { name: "err_reconnect", code: 1 }, //連線失敗
  { name: "err_token", code: 2 }, //token失敗
  { name: "err_user_status", code: 3 }, //無權限
  { name: "err_insert", code: 4 }, //新增失敗
  { name: "err_update", code: 5 }, //更新失敗
  { name: "err_delete", code: 6 }, //刪除失敗
  { name: "err_level_exist", code: 7 }, //此等級命名已存在
  { name: "err_customer_noexist", code: 8 }, //此會員編號不存在
  { name: "err_product_noexist", code: 9 } //此商品編號不存在
];

其中name的值會拿去做i18n翻譯。

--

dialog-alert.component.ts

import { Component, Inject, OnInit } from "@angular/core";
import { MAT_DIALOG_DATA, MatDialogRef } from "@angular/material/dialog";
import { filter, take } from "rxjs/operators";
import { ErrorCodeMsg } from "../../../config";

@Component({
  selector: "share-dialog-alert",
  templateUrl: "./dialog-alert.component.html",
  styleUrls: ["./dialog-alert.component.css"]
})
export class DialogAlertComponent implements OnInit {
  private ErrorCodeMsg = ErrorCodeMsg;

  constructor(
    public dialogRef: MatDialogRef<DialogAlertComponent>,
    @Inject(MAT_DIALOG_DATA) public data: { errorcode: number }
  ) {}

  ngOnInit() {
    this.dialogRef
      .keydownEvents()
      .pipe(
        filter((e: KeyboardEvent) => e.key === "Enter"),
        take(1)
      )
      .subscribe(() => {
        this.dialogRef.close();
      });
  }

  getMsgName(): string {
    if (!!this.data) {
      let result = this.ErrorCodeMsg.filter(item => item.code === this.data.errorcode);
      return !!result.length ? result[0].name : "err_fail";
    }
  }
}

--

dialog-alert.component.html

<div mat-dialog-title class="flex center">
  <mat-icon svgIcon="alert"></mat-icon>
  <span>
    {{ "dialog_alert" | translate }}
  </span>
</div>
<div mat-dialog-content class="flex center">
  <span>{{ getMsgName() | translate }}</span>
</div>

--

dialog.module.ts

import { NgModule } from "@angular/core";
import { CommonModule } from "@angular/common";
import { FormsModule, ReactiveFormsModule } from "@angular/forms";
import { TranslateModule } from "@ngx-translate/core";
import { MatIconModule, MatDialogModule, MatInputModule } from "@angular/material";
import { DialogAlertComponent } from "./alert/dialog-alert.component";
import { ValidationModule } from "../validation/validation.module";

@NgModule({
  providers: [],
  imports: [
    CommonModule,
    FormsModule,
    ReactiveFormsModule,
    TranslateModule,
    MatIconModule,
    MatDialogModule,
    MatInputModule,
    ValidationModule
  ],
  declarations: [DialogAlertComponent],
  exports: [DialogAlertComponent],
  entryComponents: [DialogAlertComponent]
})
export class DialogModule {}

(二) MateriaModule

此功能模塊是專門放置Angular Materia的相關工具。

檔案結構:

-src
  |-app
    |-app.component.css
    |-app.component.html
    |-app.component.ts
    |-app.module.ts
    |-config
        |-errorcode.ts
    |-shared
       |-dialog
       |-materia
            |-materia.module.ts
       |-shared.module.ts

--

materia.module.ts

import { NgModule } from "@angular/core";
import { LayoutModule } from "@angular/cdk/layout";
import { CdkTableModule } from "@angular/cdk/table";
import {
  MatDialogModule,
  MatPaginatorModule,
  MatDatepickerModule,
  MatCardModule,
  MatSlideToggleModule,
  MatButtonModule,
  MatIconModule,
  MatSelectModule,
  MatFormFieldModule,
  MatInputModule,
  MatTabsModule,
  MatTableModule,
  MatCheckboxModule,
  MatRadioModule,
  MatPaginatorIntl
} from "@angular/material";

@NgModule({
  imports: [
    LayoutModule,
    CdkTableModule,
    MatDialogModule,
    MatPaginatorModule,
    MatDatepickerModule,
    MatCardModule,
    MatSlideToggleModule,
    MatButtonModule,
    MatIconModule,
    MatSelectModule,
    MatFormFieldModule,
    MatInputModule,
    MatTabsModule,
    MatTableModule,
    MatCheckboxModule,
    MatRadioModule
  ],
  exports: [
    LayoutModule,
    CdkTableModule,
    MatDialogModule,
    MatPaginatorModule,
    MatDatepickerModule,
    MatCardModule,
    MatSlideToggleModule,
    MatButtonModule,
    MatIconModule,
    MatSelectModule,
    MatFormFieldModule,
    MatInputModule,
    MatTabsModule,
    MatTableModule,
    MatCheckboxModule,
    MatRadioModule
  ],
  declarations: []
})
export class MateriaModule {}

(三) PipeModule

此功能模塊是專門放置Pipe

檔案結構:

-src
  |-app
    |-app.component.css
    |-app.component.html
    |-app.component.ts
    |-app.module.ts
    |-config
        |-errorcode.ts
    |-shared
       |-dialog
       |-materia
       |-pipe
            |-pipe-tag.ts
            |-pipe-time.ts
            |-pipe.module.ts
       |-shared.module.ts

通常是放在Html裡做一些簡單指令。

--

pipe-tag.ts

基本上會拿物件的值翻譯i18n。

import { Pipe, PipeTransform } from "@angular/core";

@Pipe({
  name: "pipetag",
  pure: false
})
export class TagPipe implements PipeTransform {
  constructor() {}

  transform(value: number | string, args: any[]): any {
    if (!args.length) {
      if (typeof value === "number") {
        return value.toString();
      }
      return value;
    }

    let v = args.filter(item => {
      return item.id == value;
    });

    if (!v.length) {
      if (typeof value === "number") {
        return value.toString();
      }
      return value;
    }

    return v[0].name;
  }
}

實際運用時:

//name matcher i18n
export const ACCOUNTSTATUS = [
  { id: 1, name: "start_use" }, 
  { id: 2, name: "stop_use" }
];
<span>
  {{ r.status | pipetag: ACCOUNTSTATUS | translate }}
</span>

--

pipe-time.ts

此檔案是專門格式化moment,後續會提到。

import { Pipe, PipeTransform } from "@angular/core";
import * as _moment from "moment";
const moment = _moment;

@Pipe({
  name: "pipetime",
  pure: false
})
export class TimePipe implements PipeTransform {
  constructor() {}

  transform(value: string, args: string = "YYYY-MM-DD HH:mm:ss"): any {
    return moment(value).format(args);
  }
}

Demo內的時間套件並非採用_Angular Materia_的工具,
因為提供的時間套件只到年月日沒有時分秒,
所以之後會用ng-pick-datetimeMoment.js
https://github.com/DanielYKPan/date-time-picker

實際運用時:

<span>
  <span>{{ r.inserted | pipetime }}</span>
</span>

範例碼

https://stackblitz.com/edit/ngcms-base


上一篇
day02 基礎架構
下一篇
day04 SharedModule(二)
系列文
用Angular打造完整後台30

尚未有邦友留言

立即登入留言