如何从ControlValueAccessor获取FormControl实例

问题描述 投票:0回答:4

我有以下组件:

@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 分配表单控件的情况。

angular controls directive accessor
4个回答
80
投票

看起来injector.get(NgControl)正在抛出一个弃用警告,所以我想加入另一个解决方案:

constructor(public ngControl: NgControl) {
  ngControl.valueAccessor = this;
}

诀窍是还要从提供者数组中删除 NG_VALUE_ACCESSOR,否则你会得到循环依赖。

有关此内容的更多信息请参阅 Angular 团队的 Kara Erickson 的演讲


29
投票

一种可能的解决方案是通过

NgControl
:
 获取 
Injector

实例
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;

参见stackblitz


0
投票

要绕过

Circular dependency in DI detected
,您可以按如下所示操作:

  constructor(public inj: Injector) {}
  ngOnInit(): void {
    debugger;
    const ngControl:NgControl = this.inj.get(NgControl)
  }
© www.soinside.com 2019 - 2024. All rights reserved.