Angular mat-autocomplete - 动态添加/删除项目问题 [英] Angular mat-autocomplete - Dynamic add/delete item issue

查看:29
本文介绍了Angular mat-autocomplete - 动态添加/删除项目问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

组件的脚本

导出类 AutocompleteSimpleExample {availableItems = [{name: 'item1'}, {name: 'item2'}];items = [{name: 'item1'}, {}];新增项目() {this.items.push({});}删除项目(我:数字){this.items.splice(i, 1);}显示对象(对象){返回对象?对象名称:空;}}

组件视图

<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>添加项目</button></表单>

<块引用>

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

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

第一个自动完成字段将显示一个空值,而不是保留原来的那个.

谁能帮我弄清楚为什么值会丢失?这是处理动态数量的自动完成字段的错误方式吗?

解决方案

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

因此,Angular 需要移除所有与数据关联的 DOM 元素并重新创建它们.这意味着需要大量的 DOM 操作.

但是您可以尝试使用自定义 trackby :

<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>添加项目</button></表单>

ts:

customTrackBy(index: number, obj: any): any {回报指数;}

演示

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?

解决方案

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

这篇关于Angular mat-autocomplete - 动态添加/删除项目问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆