【问题标题】:Angular 7 Reactive forms "No value accessor for form control with unspecified name attribute"Angular 7 Reactive forms“具有未指定名称属性的表单控件的无值访问器”
【发布时间】:2018-12-14 16:32:42
【问题描述】:

我正在使用响应式表单,但我似乎对看似随机的表单字段有疑问。任何关于为什么会发生这种情况的想法都是值得考虑的。

如果有帮助,我刚刚开始使用 angular 和 material 7

有趣的是,在表单中添加和删除元素会导致其他元素出现问题。

ERROR 错误:没有未指定名称的表单控件的值访问器 属性

TS

export class VolunteerApplicationPersonalStepComponent implements OnInit 
{

  public readonly form: FormGroup;
    constructor(private fb: FormBuilder) {
        this.form = this.fb.group({
          businessTelephoneExt: [''],
          otherTelephone: [''],
          otherTelephoneExt: [''],
        });
      }
}

HTML

    <form [formGroup]="form">

     <mat-form-field>
        <input matInput i18n-placeholder placeholder="Business Extension"
               [formControl]="form.get('businessTelephoneExt')">
      </mat-form-field>

      <app-telephone-input i18n-placeholder placeholder="Other Telephone"
                           [formControl]="form.get('otherTelephone')">
      </app-telephone-input>

      <mat-form-field>
        <input matInput i18n-placeholder placeholder="Other Extension"
               [formControl]="form.get('otherTelephoneExt')">
      </mat-form-field>

      <br>

      <div class="group-margin group-min-width">
        <button mat-stroked-button color="primary" matStepperPrevious i18n>Previous</button>
        <button mat-raised-button color="primary" matStepperNext (click)="next()" i18n>Next</button>
      </div>
    </form>

正如有人建议的那样 .. formControlName="businessTelephoneExt"

App-Telephone 代码(注意它曾经有 formControl 而不是 appFormControl)

export class TelephoneInputComponent implements OnInit {

  @Input() public required = false;
  @Input() public placeholder = '';
  @Input() public appFormControl: NgControl;

  constructor() {
  }

  public ngOnInit() {
  }
}



<mat-form-field>
  <input
    matInput
    type="tel"
    [required]="required"
    [placeholder]="placeholder"
    [formControl]="appFormControl">

  <mat-hint i18n>Please enter digits only</mat-hint>

  <mat-error
    *ngIf="appFormControl.hasError('phone')"
    i18n>Invalid phone (requires 10 digits)
  </mat-error>
</mat-form-field>

【问题讨论】:

  • 你试过formControlName="businessTelephoneExt"
  • 没有区别
  • 您是否尝试注释掉您的 app-telephone-input 自定义控件,以确保它不会成为问题?
  • 似乎是自定义组件导致了它
  • 已重命名为 appFormControl,现在可以了...与组件命名约定有什么关系?

标签: angular angular-material angular7


【解决方案1】:

似乎你不能有一个名为 formControl 的 @Input()

【讨论】:

    【解决方案2】:

    我看到的一件小事是这样的:

      <app-telephone-input i18n-placeholder placeholder="Other Telephone"
                           [formControl]="form.get('otherTelephone')">
      </app-telephone-input>
    

    应该是这样的:

      <app-telephone-input i18n-placeholder placeholder="Other Telephone"
                           [appFormControl]="form.get('otherTelephone')">
      </app-telephone-input>
    

    如果你想创建一个自定义表单控制器,你应该实现 ControlValueAccessor 接口

    ControlValueAccessor {
      writeValue(obj: any): void
      registerOnChange(fn: any): void
      registerOnTouched(fn: any): void
      ...
    }
    

    如果只实现 ControlValueAccessor 接口,则可以绑定属性 formControl

    【讨论】:

      【解决方案3】:

      @ricardo 的 answer 不正确

      在使用 ControlValueAccessor 接口时,您可以有一个名为 formControl 的 @Input(),很可能您没有向您的提供程序添加 NG_VALUE_ACCESSOR 令牌。比如:

      export const VALUE_ACCESSOR: any = {
          provide: NG_VALUE_ACCESSOR,
          useExisting: forwardRef(() => MyComponent),
          multi: true,
      };
      
      @Component({
          selector: 'my-component',
          templateUrl: './my-component.component.html',
          styleUrls: ['./my-component.component.scss'],
          providers: [VALUE_ACCESSOR]
      })
      

      【讨论】:

      • 感谢更新,我想知道这是否在 v7 中出现
      • 这对我有用!
      • 另外,确保它在一个模块中 - 如果它不在模块中,也会发生同样的错误!
      【解决方案4】:

      从父组件中移除otherTelephone表单控件,从子组件中添加otherTelephone

      export class VolunteerApplicationPersonalStepComponent implements OnInit 
      {
      
        public readonly form: FormGroup;
          constructor(private fb: FormBuilder) {
              this.form = this.fb.group({
                businessTelephoneExt: [''],
                otherTelephoneExt: [''],
              });
            }
      }
      

      使用controlContainer为子组件提供父表单实例,然后注入FormGroupDiretive获取父表单实例

      apptelephoneinput.component.html

      @Component({
        selector: 'app-telephone-input',
        templateUrl: './app-telephone-input.component.html',
        styleUrls: ['./app-telephone-input.component.css'],
        viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective 
      }]
      })
      export class TelephoneInputComponent implements OnInit {   
        @Input() public required = false;
        @Input() public placeholder = '';
        childForm;
        constructor(private parentF: FormGroupDirective) { }
      
        ngOnInit() {
          this.childForm = this.parentF.form;
          this.childForm.addControl('otherTelephone', new FormControl(''))
        }
      
      }
      

      app-telephone-input.component.html

      <mat-form-field>
        <input
          matInput
          type="tel"
          [required]="required"
          [placeholder]="placeholder"
          formControl="otherTelephone">
      

      示例:https://stackblitz.com/edit/angular-fktkdk

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-02-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-08-17
        • 2019-07-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多