角垫自动完成-动态添加/删除项目问题

时间:2018-10-21 10:27:01

标签: angular angular-material ngfor mat-autocomplete

我正在尝试创建一个具有动态mat-autocomplete个字段的简单表单。但是,在某些情况下,输入的显示值会丢失

组件的脚本

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;
  }
}

组件的视图

<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>
  

我做了一个   StackBlitz   展示问题。如果您:

     
      
  1. 在第二个自动完成字段中选择一个项目(例如Item 2
  2.   
  3. 从第一个自动完成字段中删除项目(使用字段末尾的x
  4.   
  5. 点击Add Item添加另一个
  6.   
     

然后,第一个自动完成字段将显示一个空值,而不是   保留它拥有的那个。

有人可以帮我弄清楚为什么会失去价值吗?这是处理动态数量的自动完成字段的错误方法吗?

1 个答案:

答案 0 :(得分:2)

angular无法跟踪数组中的项目,也不知道已删除或添加了哪些项目。

因此,Angular需要删除与数据关联的所有DOM元素,然后再次创建它们。这意味着很多DOM操作。

但是您可以尝试使用自定义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