首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >从Angular中的自定义表单组件访问FormControl

从Angular中的自定义表单组件访问FormControl
EN

Stack Overflow用户
提问于 2017-06-24 09:29:52
回答 5查看 38.5K关注 0票数 68

在我的Angular应用程序中有一个自定义的表单控件组件,它实现了ControlValueAccessor接口。

但是,我想访问与我的组件相关联的FormControl实例。我在FormBuilder中使用反应式表单,并使用formControlName属性提供表单控件。

那么,如何从自定义表单组件内部访问 FormControl 实例呢?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2017-06-24 11:46:16

这个解决方案诞生于Angular存储库中的the discussion。如果你对这个问题感兴趣,请务必阅读它,或者更好地参与。

我研究了FormControlName指令的代码,它激发了我编写以下解决方案的灵感:

@Component({
  selector: 'my-custom-form-component',
  templateUrl: './custom-form-component.html',
  providers: [{
    provide: NG_VALUE_ACCESSOR,
    useExisting: CustomFormComponent,
    multi: true
  }]
})
export class CustomFormComponent implements ControlValueAccessor, OnInit {

  @Input() formControlName: string;

  private control: AbstractControl;


  constructor (
    @Optional() @Host() @SkipSelf()
    private controlContainer: ControlContainer
  ) {
  }


  ngOnInit () {

    if (this.controlContainer) {
      if (this.formControlName) {
        this.control = this.controlContainer.control.get(this.formControlName);
      } else {
        console.warn('Missing FormControlName directive from host element of the component');
      }
    } else {
      console.warn('Can\'t find parent FormGroup directive');
    }

  }

}

我将父FormGroup注入到组件中,然后使用通过formControlName绑定获得的控件名称从组件中获取特定的FormControl

但是,请注意,此解决方案是专门为在主机元素上使用FormControlName指令的用例量身定做的。它在其他情况下不会起作用。为此,您需要添加一些额外的逻辑。如果你认为这个问题应该由Angular来解决,请务必访问the discussion

票数 60
EN

Stack Overflow用户

发布于 2018-07-02 04:56:19

当通过[formControl]指令进行绑定时,使用formControlName作为输入参数不起作用。

这是一个不需要任何输入参数就可以双向工作的解决方案。

export class MyComponent implements AfterViewInit {

  private control: FormControl;

  constructor(
    private injector: Injector,
  ) { }

  // The form control is only set after initialization
  ngAfterViewInit(): void {
    const ngControl: NgControl = this.injector.get(NgControl, null);
    if (ngControl) {
      this.control = ngControl.control as FormControl;
    } else {
      // Component is missing form control binding
    }
  }
}

票数 53
EN

Stack Overflow用户

发布于 2020-05-18 02:52:20

基于之前的答案和在评论中找到的documentation,这是我对基于ControlValueAccessor的组件最干净的解决方案的看法。

// No FormControl is passed as input to MyComponent
<my-component formControlName="myField"></my-component>
export class MyComponent implements AfterViewInit, ControlValueAccessor  {

  constructor(@Optional() @Self() public ngControl: NgControl) {
    if (ngControl != null) {
      // Setting the value accessor directly (instead of using
      // the providers) to avoid running into a circular import.
      ngControl.valueAccessor = this;
    }
  }

    ngAfterContentInit(): void {
       const control = this.ngControl && this.ngControl.control;
       if (control) {
          // FormControl should be available here
       }
    }
}
票数 12
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44731894

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档