串接階段發現最常報錯的就是前後端命名不一樣,就算我都寫好型別了,不知道有沒有更智慧的防呆辦法可以處理,而且有的時候串接起來才發現API開的跟畫面需求有點不一樣,一遍就全部開對而且理解業務邏輯的人真是老江湖啊,就算需求是我自己開的,我都需要微調了
以下是程式碼,因為有串DB但是還沒加驗證,所以沒有放上 stackblitz
import { Component, ElementRef, OnInit, ViewChild, ViewContainerRef } from '@angular/core';
import { NzModalService } from 'ng-zorro-antd/modal';
import { CRUD, EditType } from 'src/app/feature/enum/furniture.enum';
import { Furniture, StorageItem } from 'src/app/feature/interface/furniture.interface';
import { FurnitureModalComponent } from 'src/app/feature/modal/furniture-modal/furniture-modal.component';
import { StorageModalComponent } from 'src/app/feature/modal/storage-modal/storage-modal.component';
import { StorageService } from './service/storage.service';
@Component({
selector: 'app-day18',
templateUrl: './day18.component.html',
styleUrls: ['./day18.component.scss']
})
export class Day18Component implements OnInit {
...
onPopoverButtonClick(editType: EditType,) {
switch (editType) {
case EditType.furniture:
this.isPopoverVisible = false;
this.furnitureModal(this.furnitureSetting);
break;
case EditType.storage:
this.isPopoverVisible = false;
// this.storageService.getStorageItemsByFurnitureId(this.furnitureSetting._id).subscribe((res)=>{
this.storageModal(this.furnitureSetting._id);
// })
break;
default:
break;
}
}
...
private storageModal(furnitureId:string): void {
this.modal.create({
// nzTitle: tplTitle,
nzContent: StorageModalComponent,
nzFooter: null,
nzWidth: '95vw',
// nzMaskClosable: false,
// nzClosable: false,
nzData: {
// listOfData: itemList,
furnitureId
},
nzOnOk: () => console.log('Click ok')
});
}
...
}
<app-default-modal [name]="'收納明細'">
<div class="text-end py-2">
<button nz-button style="width: 120px;" (click)="add()" [disabled]="isEditing"nzType="primary"><span nz-icon nzType="plus"
nzTheme="outline"></span></button>
</div>
<nz-table #editRowTable nzBordered [nzData]="listOfData" nzTableLayout="fixed">
<thead>
<tr>
<th nzWidth="20%">物品名</th>
<th nzWidth="8%">數量</th>
<th nzWidth="15%">單位</th>
<th nzWidth="40%">備註</th>
<th nzWidth="15%">Action</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let data of editRowTable.data">
<ng-container *ngIf="!editCache[data._id].edit; else editTemplate">
<td>{{ data.name }}</td>
<td>{{ data.quantity }}</td>
<td>{{ data.unit }}</td>
<td>{{ data.note }}</td>
<td>
<div class="d-flex justify-content-around">
<span nz-icon nzType="edit" nzTheme="outline" (click)="startEdit(data._id)" [class.disabled]="isEditing"></span>
<span nz-icon nzType="delete" nzTheme="outline" (click)="deleteRow(data._id)" [class.disabled]="isEditing"></span>
</div>
</td>
</ng-container>
<ng-template #editTemplate>
<td><input type="text" nz-input [(ngModel)]="editCache[data._id].data.name" /></td>
<td><input type="text" nz-input [(ngModel)]="editCache[data._id].data.quantity" /></td>
<td><input type="text" nz-input [(ngModel)]="editCache[data._id].data.unit" /></td>
<td><input type="text" nz-input [(ngModel)]="editCache[data._id].data.note" /></td>
<td>
<div class="d-flex justify-content-around">
<a nz-popconfirm nzPopconfirmTitle="Sure to save?"
(nzOnConfirm)="saveEdit(data._id,data.isNew)" class="save">Save</a>
<a nz-popconfirm nzPopconfirmTitle="Sure to cancel?"
(nzOnConfirm)="cancelEdit(data._id)">Cancel</a>
</div>
</td>
</ng-template>
</tr>
</tbody>
</nz-table>
</app-default-modal>
import { Component, inject } from '@angular/core';
import { NZ_MODAL_DATA, NzModalRef } from 'ng-zorro-antd/modal';
import { StorageItem } from '../../interface/furniture.interface';
import { StorageService } from 'src/app/page/day18/service/storage.service';
@Component({
selector: 'app-storage-modal',
templateUrl: './storage-modal.component.html',
styleUrls: ['./storage-modal.component.scss']
})
export class StorageModalComponent {
listOfData: StorageItem[] = [];
readonly #modal = inject(NzModalRef);
readonly nzModalData: { furnitureId: string } = inject(NZ_MODAL_DATA);
editCache: { [key: string]: { edit: boolean; data: StorageItem } } = {};
isEditing: boolean = false; // 新增此行
constructor(
private storageService: StorageService
) {
this.getStorageItemList();
}
ngOnInit(): void {
}
private updateEditCache(): void {
this.listOfData.forEach(item => {
this.editCache[item._id] = {
edit: false,
data: { ...item }
};
});
}
private getStorageItemList() {
this.storageService.getStorageItemsByFurnitureId(this.nzModalData.furnitureId)
.subscribe((res) => {
if (res) {
this.listOfData = res;
this.updateEditCache();
}
})
}
add() {
if (this.isEditing) return; // 如果正在編輯,則不允許新增
this.listOfData = [
...this.listOfData,
{
_id: this.listOfData.length.toString(),
name: '', quantity: 0, unit: '個', note: '',
parentItemId: this.nzModalData.furnitureId,
furnitureId: this.nzModalData.furnitureId,
isNew: true,
}
]
this.updateEditCache();
this.startEdit((this.listOfData.length - 1).toString());
}
startEdit(id: string): void {
if (this.isEditing) return; // 如果正在編輯,則不允許新的編輯
this.isEditing = true; // 設置編輯狀態
this.editCache[id].edit = true;
}
cancelEdit(id: string): void {
const index = this.listOfData.findIndex(item => item._id === id);
this.editCache[id] = {
data: { ...this.listOfData[index] },
edit: false
};
this.isEditing = false; // 重置編輯狀態
}
deleteRow(id: string): void {
if (this.isEditing) return; // 如果正在編輯,則不允許刪除
this.storageService.deleteStorageItem(id).subscribe(() => {
this.getStorageItemList();
});
}
saveEdit(id: string, isNew: boolean): void {
if (isNew) {
const data: any = this.editCache[id].data;
delete data._id;
delete data.isNew;
this.storageService.createStorageItem(this.editCache[id].data).subscribe(() => {
this.getStorageItemList();
this.isEditing = false; // 重置編輯狀態
});
} else {
const data: any = this.editCache[id].data;
delete data.isNew;
this.storageService.updateStorageItem(id, this.editCache[id].data).subscribe(() => {
this.getStorageItemList();
this.isEditing = false; // 重置編輯狀態
});
}
}
}
.disabled {
opacity: 0.5;
pointer-events: none;
}