angular - Angular 指令从 NgModel 或 FormControlName 获取值
问题描述
我有一个指令来检查表单组件是使用反应式表单还是模板驱动创建的。我用它来维护使用相同指令的其他组件之间的兼容性。在 Angular 8 中一切都很好,但在 Angular 9 中却不行。
在我的指令中,我有一个方法来获取和设置字段值,设置字段状态为脏或触摸,但要做到这一点,我有条件知道组件使用了什么表单。
不幸的是,在 Angular 9 中,我不能这样做,因为我不知道该怎么做。请,如果有人可以帮助我,我将不胜感激。
大声说出我的指令
@Directive({
selector: '[appSelect2Cities]',
})
export class Select2CitiesDirective implements OnChanges, AfterContentChecked, AfterViewInit {
input: any;
// Cast one of the types to a variable
@ContentChild(NgModel, { static: false }) model: NgModel;
@ContentChild(FormControlName, { static: false }) control: FormControlName;
// ... some code here
ngOnChanges(changes: SimpleChanges): void {
if (this.model) {
// ... some code here
} else if (this.control) {
// ... some code here
}
}
ngAfterViewInit(): void {
this.input = this.model || this.control;
if (this.input === undefined) { // <-- Always undefined here
throw new Error('That directive needs to be used by ngModel or FormControlName');
}
this.initializeSelect2();
}
// ... some code here
}
我使用响应式表单时的示例
<select
appSelect2Cities
class="form-control"
formControlName="cities"
[value]="citiesValue"
placeholder="Select a City"
(itemSelected)="onCitySelected($event)"
>
</select>
以及我使用模板驱动时的示例
<select
appSelect2Cities
class="form-control"
name="city"
[(ngModel)]="address.city"
>
</select>
解决方案
终于,我找到了我的问题的答案!
我不知道为什么@ContentChild
在这种情况下不能以同样的方式工作,但我相信这与 Angular 团队为修复查询中的错误和令人惊讶的行为所做的更改有关。看到 https://angular.io/guide/static-query-migration
在我的情况下,解决方案只是在构造函数中声明NgModel
andFormControlName
而不是使用@ContentChold
,如下所示
@Directive({
selector: '[appSelect2Cities]',
})
export class Select2CitiesDirective implements OnChanges, AfterContentChecked, AfterViewInit {
input: any;
constructor(@Optional() private model: NgModel, @Optional() private control: FormControlName) {}
// ... some code here
ngOnChanges(changes: SimpleChanges): void {
if (this.model) {
// ... some code here
} else if (this.control) {
// ... some code here
}
}
ngAfterViewInit(): void {
this.input = this.model || this.control;
if (this.input === undefined) { // <-- Now works fine
throw new Error('That directive needs to be used by ngModel or FormControlName');
}
this.initializeSelect2();
}
// ... some code here
}
推荐阅读
- python - 从几年的时间序列中删除一天中的某些小时v - python
- cordova - 科尔多瓦插件是否与电容器(离子)一起使用
- mysql - Windows 更新后 Xammp MySQL 无法启动
- google-bigquery - 根据另一个表中的开始日期和结束日期对值求和
- ios - 导航到主页后,swrevealcontroller 无法正常工作
- java - vertx.setPeriodic函数时间间隔减小的问题
- r - 在 32 位计算机上重新安装 data.table 时遇到问题
- sql - ToDate 参数未在 SSRS 报告中显示当前日期记录
- coq - 无法将变量绑定到包装的打开公式
- leaflet - 创建地图后更改 fadeAnimation 选项