首页 > 解决方案 > Angular 7 材质 | mat-select 按键上的自动填充在清除后不会重置源

问题描述

我希望能够尽可能只用键盘来控制这个组件。我通过确保您在制表机上获得正确的控制来做到这一点。在最后一个表单字段上,当您按下 Tab 时,它会将临​​时项目添加到列表中,重置临时项目,然后将您的注意力重新集中在第一个行项目字段上。

问题是,如果我想让 2 个订单项与同一个帐户,我第二次尝试通过按帐户名称的第一个字母(在本例中为“c”)来选择它,它会跳过一个选项,因为它以前被选中. 我希望在清除临时项目时重置选项。

为了重现我试图描述的问题:

输入任意数字作为金额

点击标签

点击 c(它将转到“汽车保险”)

点击选项卡提交该行并再次从金额开始

输入金额

点击标签

现在,如果您再次尝试按“c”,“汽车保险”不再是第一个选项。由于某种原因,它默认为列表中的下一项。

如果我使用标准和标签,我不会遇到同样的问题,只有当我使用材料等价物时。

这是相关代码 https://stackblitz.com/edit/angular-tab8tm

标签: angularangular-material

解决方案


因为从技术上讲,您仍在使用相同的mat-select...而不是创建新的...旧值仍在mat-select...

keyManager组件背后有一个MatSelect管理所有这些逻辑的组件,并且因为您将当前值推入新数组并重置ngModel... 您还需要访问keyManager和默认值。


templateRef为根创建mat-select一个#select

<mat-form-field class="temp-item-field" *ngIf="accounts">
        <mat-select #select [(ngModel)]="tempItem.accountId" placeholder="Account">
          <mat-option *ngFor="let account of accounts" [value]="account.id">{{account.name}}</mat-option>
        </mat-select>
      </mat-form-field>

在组件中创建@ViewChild以获取参考

 @ViewChild('select') _select

在您addItem()设置activeItemandactiveItemIndex为它们的默认值。

addItem() {
    if (this.tempItem.amount && this.tempItem.accountId) {
      this.tempItem.transactionId = this.transaction.id;
      this.transaction.transactionItems.push(this.tempItem);
      this.tempItem = new TransactionItem();
      this.focusTransactionAmount();
      this._select['_keyManager']['_activeItem'] = undefined;
      this._select['_keyManager']['_activeItemIndex'] = -1;     
    }
  }

堆栈闪电战

https://stackblitz.com/edit/angular-ywrz7v?embed=1&file=src/app/app.component.ts


就个人而言,我建议您探索使用ReactiveForms它并通过...生成新字段,FormControlArray而不是将当前值从当前字段“转移”到新字段中,并重置原始根字段...

您基本上可以做与您现在正在做的相反的事情......创建新字段,formControls将当前输入的值statetab在原处......并且基本上能够避免这种情况并ngModel一起使用。

请参阅这个 SO 答案,其中我提供了反应式表单如何在*ngFor循环中工作的演练......以及 stackblitz 示例。

stackblitzbuildForm()中的 本质上是您需要addItem()推送新formControls的内容,它会自动在视图中创建新字段。

使用 *ngFor 并从中提交值的动态表单


推荐阅读