问题
I'm trying to create a simple form with a dynamic number of mat-autocomplete
fields. However, in some cases, the inputs' displayed values get lost.
Component's script
export class AutocompleteSimpleExample {
availableItems = [{name: 'item1'}, {name: 'item2'}];
items = [{name: 'item1'}, {}];
addItem() {
this.items.push({});
}
deleteItem(i: number) {
this.items.splice(i, 1);
}
displayObject(obj) {
return obj ? obj.name : null;
}
}
Component's view
<form>
<mat-form-field *ngFor="let item of items; let i = index">
<input matInput [(ngModel)]="items[i]" [matAutocomplete]="itemAutocomplete" name="items[{{i}}]">
<mat-autocomplete #itemAutocomplete="matAutocomplete" [displayWith]="displayObject">
<mat-option *ngFor="let item of availableItems" [value]="item">{{item.name}}</mat-option>
</mat-autocomplete>
<button mat-button mat-icon-button matSuffix type="button" (click)="deleteItem(i)"><mat-icon>close</mat-icon></button>
</mat-form-field>
<button class="btnType01" mat-raised-button type="button" (click)="addItem()"><mat-icon>add</mat-icon>Add Item</button>
</form>
I've made a StackBlitz to showcase the issue. If you:
- Select an item in the second autocomplete field (e.g.
Item 2
)- Remove the item from the first autocomplete field (using the
x
at the end of the field)- Click
Add Item
to add another oneThe first autocomplete field will then show an empty value, instead of keeping the one it had.
Could anyone help me figure out why the value is lost? Is this the wrong way of dealing with a dynamic number of autocomplete fields?
回答1:
angular can’t keep track of items in the array and has no knowledge of which items have been removed or added.
As a result, Angular needs to remove all the DOM elements that associated with the data and create them again. That means a lot of DOM manipulations.
but you can try with a custom trackby :
<form>
<mat-form-field *ngFor="let item of items; let i = index; trackBy:customTrackBy">
<input matInput [(ngModel)]="items[i]" [matAutocomplete]="itemAutocomplete"
name="items[{{i}}]">
<mat-autocomplete #itemAutocomplete="matAutocomplete" [displayWith]="displayObject">
<mat-option *ngFor="let item of availableItems" [value]="item">{{item.name}} </mat-option>
</mat-autocomplete>
<button mat-button mat-icon-button matSuffix type="button" (click)="deleteItem(i)"><mat-icon>close</mat-icon></button>
</mat-form-field>
<button class="btnType01" mat-raised-button type="button" (click)="addItem()"><mat-icon>add</mat-icon>Add Item</button>
</form>
ts:
customTrackBy(index: number, obj: any): any {
return index;
}
DEMO
来源:https://stackoverflow.com/questions/52914319/angular-mat-autocomplete-dynamic-add-delete-item-issue