【问题标题】:Form Control for select doesn't update value when options' list changes表单控件选择不会在选项列表更改时更新值
【发布时间】:2019-09-05 04:49:08
【问题描述】:

我正在使用 Angular 的反应式表单,其中一个表单控件是选择输入。选项动态更改,当用户选择了一个值然后选项更改时,旧值仍然是表单控件的值,即使它不再在选项列表中(因此不是可接受的值)。

HTML:

<mat-select formControlName="example">
    <mat-option *ngFor="let example of examples_filtered" [value]="example">
        {{ example.frontend_name }}
    </mat-option>
</mat-select>

打字稿:

this.myForm.controls['someControl'].valueChanges.subscribe(
    (value) => {
        this.examples_filtered = [];
        this.examples.forEach((example: Example, index: Number, array: Example[]) => {
          if (example.value_id === value.id) {
            this.examples_filtered.push(example);
          }
        });
    }
);

由于此表单控件使用 Validators.required,因此预期的行为是表单控件被清空(即值设置为 null)并且其状态更改为“无效”。

实际结果是,表单控件中仍然选择了之前过滤示例中的旧值,并且 Validators.required 将表单控件标记为有效。

我应该手动执行此操作(即自定义代码)还是 Angular 支持解决此问题的机制?

【问题讨论】:

  • 不确定这是否是问题,但似乎您在代码中给出了错误的控件名称。你能试试this.myForm.controls['example'].valueChanges而不是this.myForm.controls['someControl'].valueChanges吗?
  • @JustShadow 这是因为我使用 ['someControl'] 的值来过滤示例。当 ['someControl'] 的值发生变化时,我正在过滤示例,这会更改选项列表。
  • 我不认为 Angular 可以在这里拦截您的更改,因为您实际上并未更改 formControl 值(如果您隐藏属性并不意味着您更改了所选值)。也许你应该在订阅函数的末尾写上this.myForm.controls['example'].setValue(null)(没有选择)或this.myForm.controls['example'].setValue(this.examples_filtered[0])(选择第一个元素)。
  • @FedericoGalfione 我已经添加了this.myForm.controls['example'].reset(),现在我得到了预期的行为。谢谢!
  • @NikolayNikolov 使用 reset() 不是可行的方法(并且对我不起作用)。请在下面查看我的答案以获得简单的干净解决方案。

标签: angular html-select angular-reactive-forms


【解决方案1】:

以下将根据需要进行。关键是使用 Angular 的 selectionChange 事件,它将按预期直接更新您的表单控件(在输入附加的事件处理程序之前)。

模板

<mat-select formControlName="example" (selectionChange)="this.exampleSelectionChangedHandler($event)">
    <mat-option *ngFor="let example of examples_filtered" [value]="example">
        {{ example.frontend_name }}
    </mat-option>
</mat-select>

组件

public exampleSelectionChangedHandler(e: MouseEvent){
  this.examples_filtered = [];
  this.examples.forEach((example: Example, index: Number, array: Example[]) => {

  if (example.value_id === value.id) {
    this.examples_filtered.push(example);
  }
}

奇怪的是 selectionChange 选项不是“智能感知的”,但绝对是一个 mat-select 指令,因为我们可以阅读here

@Output() selectionChange: EventEmitter

当用户更改所选值时发出的事件。

【讨论】:

    猜你喜欢
    • 2021-08-24
    • 2017-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-07
    相关资源
    最近更新 更多