TypeScript - 在 Angular 的對話框視窗中使用 mat chip 列表?
然後當使用者輸入一些資料時,應該以預先填充的 mat-chips 列表格式顯示從資料庫取得的相關甜點列表數據如下:(如果這不可能,我們可以顯示一個從資料庫預先填充的可用甜點下拉選單,讓使用者從中選擇),但已經選擇的值(重複)不應該出現在下拉選單中,也不應該透過輸入再次提示使用者選擇,無論對話框仍然開啟或已關閉再重新打開。因為所選甜點應該是唯一的,因為這個 chip 資料將被存儲在資料庫的另一個表中。
使用者可以從顯示的可用項目列表中刪除或添加任何他想要的芯片,然後點擊提交。但這裡的條件應該是,一旦一個芯片項目被選中(不關閉該項目即視為已選擇提交),就不能再次通過輸入或者之前的提交來選擇重複的芯片項目。這意味著:例如,如果我有5個預先填充的芯片項目,如圖所示,使用者不能輸入新的芯片項目並提交;另外,如果芯片4和芯片5已被選中,而芯片1、芯片2、芯片3已從顯示列表中關閉(刪除),那麼提交時只能將不重複的1個芯片4和1個芯片5傳送到通過按鈕點擊事件調用此對話框的頁面上。再者,當使用者再次打開此對話框時,之前選擇的芯片4和5不應再次出現在模態芯片列表中。
我已經嘗試按照 Angular Material 文檔中所述完全實現自動完成類型的 mat chip 列表,如下所示,但那會打開一個下拉菜單,而不是所需的格式。
desserts.component.html:
<div mat-dialog-content>
<form>
<div>
<mat-form-field appearance="outline">
<mat-label>Dessert*</mat-label>
<mat-chip-list multiple #chipList>
<mat-chip
*ngFor="let dessert of desserts"
[selectable]="selectable"
[removable]="removable"
(removed)="remove(dessert)">
{{dessert}}
<mat-icon matChipRemove *ngIf="removable">cancel</mat-icon>
</mat-chip>
<input
placeholder="Dessert Name"
#dessertInput
[formControl]="dessertListCtrl"
[matAutocomplete]="auto"
[matChipInputFor]="chipList"
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
[matChipInputAddOnBlur]="addOnBlur"
(matChipInputTokenEnd)="add($event)">
</mat-chip-list>
<mat-autocomplete #auto="matAutocomplete" (optionSelected)="selected($event)">
<mat-option *ngFor="let dessert of filteredDesserts | async" [value]="dessert">
{{dessert}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
<button mat-button (click)="onSubmit()">Submit</button>
</div>
</form>
</div>
desserts.component.ts:
export class DessertsComponent{
selectable = true;
removable = true;
addOnBlur = true;
separatorKeysCodes: number[] = [ENTER, COMMA];
dessertListCtrl = new FormControl();
filteredDesserts: Observable<string[]>;
desserts: string[] = [];
dessertsList: any = [];
@ViewChild('dessertInput',{static: false}) dessertInput: ElementRef<HTMLInputElement>;
@ViewChild('auto',{static: false}) matAutocomplete: MatAutocomplete;
constructor(
private dbService: DBService,
public dialogRef: MatDialogRef<DessertsComponent>,
@Inject(MAT_DIALOG_DATA) public data: any,
) {
this.dessertsListData();
this.filteredDesserts = this.dessertListCtrl.valueChanges.pipe(
startWith(null),
map((dessert: string | null) => dessert ? this._filter(dessert) : this.dessertsList.slice()));
}
dessertsListData(){
this.dbService.dessertsListData().subscribe(
(response: any) => {
this.dessertsList = response;
});
}
add(event: MatChipInputEvent): void {
if (!this.matAutocomplete.isOpen) {
const input = event.input;
const value = event.value;
if ((value || '').trim()) {
this.desserts.push(value.trim());
}
if (input) {
input.value = '';
}
this.dessertListCtrl.setValue(null);
}
}
remove(dessert: string): void {
const index = this.desserts.indexOf(dessert);
if (index >= 0) {
this.desserts.splice(index, 1);
}
}
selected(event: MatAutocompleteSelectedEvent): void {
this.desserts.push(event.option.viewValue);
this.dessertInput.nativeElement.value = '';
this.dessertListCtrl.setValue(null);
}
private _filter(value: string): string[] {
const filterValue = value.toLowerCase();
return this.dessertsList.filter(dessert => dessert.toLowerCase().indexOf(filterValue) === 0);
}
onSubmit(){
this.dialogRef.close({data: this.desserts});
}
}
這個甜點組件正在被從另一個組件調用 this.dialog.open(DessertsComponent)
我不是 Angular Material(v7) 的專家,所以如果有人能提供這個問題的解決方案,我將非常感激和感謝。

