Angular mat-autocomplete - Dynamic add/delete item issue

故事扮演 提交于 2019-12-11 16:37:27

问题


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:

  1. Select an item in the second autocomplete field (e.g. Item 2)
  2. Remove the item from the first autocomplete field (using the x at the end of the field)
  3. Click Add Item to add another one

The 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!