如何从ControlValueAccessor获取FormControl实例

34

我有以下组件:

@Component({
    selector: 'pc-radio-button',
    templateUrl: './radio-button.component.html',
    providers: [
        {provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => FieldRadioButtonComponent), multi: true}
    ]
})
export class RadioButtonComponent implements ControlValueAccessor {
    ...
}

我可以通过这些输入来分配和更改值:

<pc-radio-button [formControl]="formControl"></pc-radio-button>
<pc-radio-button [formControlName]="inputControlName"></pc-radio-button>

然而,我需要该组件直接访问所分配的formControl,因为我需要根据其状态添加样式。

创建@input() formControl并不能解决问题。因为它无法涵盖通过formControlName分配表单控件的情况。

3个回答

74

看起来 injector.get(NgControl) 引发了一个弃用警告,因此我想提供另一种解决方案:


It looks like injector.get(NgControl) is throwing a deprecation warning, so I wanted to chime in with another solution:
constructor(public ngControl: NgControl) {
  ngControl.valueAccessor = this;
}

关键是还要从提供者数组中删除NG_VALUE_ACCESSOR,否则会出现循环依赖。

有关此更多信息,请参阅 Angular 团队的 Kara Erickson 的 这个讲座


7
这应该是2019年Angular 7中被接受的解决方案。 - AsGoodAsItGets
1
请问您能展示一下哪里出现了弃用警告吗? - yurzui
5
值得一提的是,她的演讲非常值得你花时间去听。但如果你正在寻找特定的“NgControl”部分,可以从19:07开始。 - Eric Liprandi
1
谢谢 @EricLiprandi,非常有用。 - Leandro Galluppi
6
当我这样做时,会出现“在 DI 中检测到循环依赖”的错误提示。 - Ties
显示剩余2条评论

28

一个可能的解决方案是通过Injector获取NgControl实例:

import { NgControl } from '@angular/forms';
export class PasswordComponent implements ControlValueAccessor, AfterViewInit {
  ...
  ngControl: NgControl;

  constructor(private inj: Injector) {
    ...
  }

  ngAfterViewInit() {
    this.ngControl = this.inj.get(NgControl)
  }

然后您可以获取状态,如下所示

ngControl.control.status

也请参阅


3
从我的stackblitz问题的最初回答可以看出,另一个解决方案是将NG_VALIDATORS添加为提供者。 因此,在我们的validate函数中,我们可以将控件存储在变量中。
public validate(c: FormControl) {
  if (!this.control)
    this.control=c;
  return null;

请查看这个链接,它包含了最初的回答。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接