Angular Material 绑定到事件取消 valueChanges 订阅
Angular Material binding to event cancels valueChanges subscription
我有一个非常基本的自动完成设置 Angular Material (6)。这是基本实现:
<mat-form-field>
<input type="text" matInput placeholder="Company" formControlName="company" [matAutocomplete]="autoCo"/>
<mat-autocomplete #autoCo="matAutocomplete" [displayWith]="displayCo">
<mat-option *ngFor="let company of filteredCompanies | async" [value]="company">
{{ company.companyName }}
</mat-option>
</mat-autocomplete>
</mat-form-field>
这没有问题。但是,我希望在做出选择时发生一些事情。为此,我将 (optionSelected)="onSelectionChanged($event)"
添加到 mat-autocomplete
元素。最初,一切都按预期工作(过滤选项有效)。做出选择后,onSelectionChanged
函数也会按预期触发。
但是,在做出选择后,无论我做了什么更改,所选项目都是自动完成下拉列表中唯一可用的项目。所以即使我删除了输入中的所有文本,我仍然只能看到之前选择的选项。我希望看到完整的列表。
在ngOnInit
中,我有:
this.filteredCompanies = this.companyForm.get("company").valueChanges.pipe(
debounceTime(200))
.pipe(mergeMap(val => this.filter(val)));
如果我绑定到 optionSelected
,valueChanges
订阅似乎会结束。如果我不绑定到 optionSelected
,选项列表会按预期更新。
我是否错误地绑定了 optionSelected
事件?我是否必须从 onSelectionChanged()
中重新订阅表单 valueChanges?如果是,为什么?
关于它的价值,这里是一些其他相关代码:
@Output()
optionSelected = new EventEmitter();
onSelectionChanged(event: any) {
console.log(event);
this.optionSelected.emit(event);
}
您真的订阅了 valueChanges
吗?从您的代码来看,它看起来不像。我想你错过了一个 .subscribe()
电话。
this.filteredCompanies = this.companyForm.get("company").valueChanges
.pipe(debounceTime(200))
.pipe(mergeMap(val => this.filter(val)))
.subscribe(() => {});
你绑定到 onSelectionChanged
也有点不对,这个:
@Output()
optionSelected = new EventEmitter();
onSelectionChanged(event: any) {
console.log(event);
this.optionSelected.emit(event);
}
可以简化为:
onSelectionChanged(event: any) {
console.log(event);
// do what you want here
}
为了尝试回答您的问题,我首先尝试重现该问题。我创建了以下内容:
我不得不对您没有包含的代码做出一些假设,但是对于您包含的代码我没有进行实质性修改(除了偶尔添加 console.log)。
如您在 StackBlitz 中所见,您所描述的问题并未发生。
这可能与您未共享的代码有关。请将 StackBlitz 与您的代码进行比较。如果有差异,请分享不同的代码,我会更新 StackBlitz 重新测试。
一些注意事项:
- 我刚刚为您的代码使用了默认值 'hello-component'。
- 我创建了一个简单的 filter() 方法,因为您没有为此提供代码。
- 我创建了一个简单的 displayCo() 方法,因为您没有提供此代码。
- 我假设父组件通过名为
companies
的输入向该子组件提供了选项列表,这是一个 Company[]
.
- 我还对您创建表单的方式做了一些假设,因为您的问题中也没有包含这些。
我希望这有助于找到问题的根本原因。
更新
您在以下评论中提供的经过编辑的 StackBlitz 代码正在调用:
this.companyForm.setControl("company", this.setCompany(newSelection));
但是 this.setCompany
returns 一个 FormGroup 和 .setControl()
需要一个 FormControl 作为第二个参数。您应该能够简单地用这样的东西更新现有的 FormGroup:
this.companyForm.get('company').setValue(newSelection);
我有一个非常基本的自动完成设置 Angular Material (6)。这是基本实现:
<mat-form-field>
<input type="text" matInput placeholder="Company" formControlName="company" [matAutocomplete]="autoCo"/>
<mat-autocomplete #autoCo="matAutocomplete" [displayWith]="displayCo">
<mat-option *ngFor="let company of filteredCompanies | async" [value]="company">
{{ company.companyName }}
</mat-option>
</mat-autocomplete>
</mat-form-field>
这没有问题。但是,我希望在做出选择时发生一些事情。为此,我将 (optionSelected)="onSelectionChanged($event)"
添加到 mat-autocomplete
元素。最初,一切都按预期工作(过滤选项有效)。做出选择后,onSelectionChanged
函数也会按预期触发。
但是,在做出选择后,无论我做了什么更改,所选项目都是自动完成下拉列表中唯一可用的项目。所以即使我删除了输入中的所有文本,我仍然只能看到之前选择的选项。我希望看到完整的列表。
在ngOnInit
中,我有:
this.filteredCompanies = this.companyForm.get("company").valueChanges.pipe(
debounceTime(200))
.pipe(mergeMap(val => this.filter(val)));
如果我绑定到 optionSelected
,valueChanges
订阅似乎会结束。如果我不绑定到 optionSelected
,选项列表会按预期更新。
我是否错误地绑定了 optionSelected
事件?我是否必须从 onSelectionChanged()
中重新订阅表单 valueChanges?如果是,为什么?
关于它的价值,这里是一些其他相关代码:
@Output()
optionSelected = new EventEmitter();
onSelectionChanged(event: any) {
console.log(event);
this.optionSelected.emit(event);
}
您真的订阅了 valueChanges
吗?从您的代码来看,它看起来不像。我想你错过了一个 .subscribe()
电话。
this.filteredCompanies = this.companyForm.get("company").valueChanges
.pipe(debounceTime(200))
.pipe(mergeMap(val => this.filter(val)))
.subscribe(() => {});
你绑定到 onSelectionChanged
也有点不对,这个:
@Output()
optionSelected = new EventEmitter();
onSelectionChanged(event: any) {
console.log(event);
this.optionSelected.emit(event);
}
可以简化为:
onSelectionChanged(event: any) {
console.log(event);
// do what you want here
}
为了尝试回答您的问题,我首先尝试重现该问题。我创建了以下内容:
我不得不对您没有包含的代码做出一些假设,但是对于您包含的代码我没有进行实质性修改(除了偶尔添加 console.log)。
如您在 StackBlitz 中所见,您所描述的问题并未发生。
这可能与您未共享的代码有关。请将 StackBlitz 与您的代码进行比较。如果有差异,请分享不同的代码,我会更新 StackBlitz 重新测试。
一些注意事项:
- 我刚刚为您的代码使用了默认值 'hello-component'。
- 我创建了一个简单的 filter() 方法,因为您没有为此提供代码。
- 我创建了一个简单的 displayCo() 方法,因为您没有提供此代码。
- 我假设父组件通过名为
companies
的输入向该子组件提供了选项列表,这是一个Company[]
. - 我还对您创建表单的方式做了一些假设,因为您的问题中也没有包含这些。
我希望这有助于找到问题的根本原因。
更新
您在以下评论中提供的经过编辑的 StackBlitz 代码正在调用:
this.companyForm.setControl("company", this.setCompany(newSelection));
但是 this.setCompany
returns 一个 FormGroup 和 .setControl()
需要一个 FormControl 作为第二个参数。您应该能够简单地用这样的东西更新现有的 FormGroup:
this.companyForm.get('company').setValue(newSelection);