簡體   English   中英

Angular - 表單內的組件 - formControlName 必須與父級一起使用

[英]Angular - components inside form - formControlName must be used with a parent

我想重用單個組件來動態生成表單輸入字段並想出了這段代碼

form-field.component.html

<label *ngIf="formLabel">{{formLabel}}</label>
<input
        type="text"
        class="form-control"
        [formControlName]="formFieldName"
        [ngClass]="{
              'is-invalid': formField.dirty && formField.errors
            }"
        [placeholder]="placeholder"
/>
<div
        *ngIf="formField.dirty && formField.errors"
        class="invalid-feedback"
>
<span *ngIf="formField.errors.required">
    {{requiredMessage}}
</span>
    <div *ngIf="formField.errors.pattern">
    <span *ngFor="let message of patternErrorMessages">
        {{message}}
    </span>
    </div>
</div>

form-field.component.ts

  @Input() formField: AbstractControl;
  @Input() patternErrorMessages: string[];
  @Input() formLabel: string;
  @Input() formFieldName: string;
  @Input() placeholder: string;
  @Input() form: FormGroup;

  requiredMessage = FORM_REQUIRED;

  constructor() { }

  ngOnInit(): void {
    this.patternErrorMessages = this.patternErrorMessages.length === 0 ? ['Pattern Mismatch'] : this.patternErrorMessages;
  }

父組件.html

<form (ngSubmit)="validSubmit(myFormGroup)" [formGroup]="myFormGroup">
         <div class="form-group">
          <app-form-field
                  [formField]="myFormGroup.controls.name"
                  [patternErrorMessages]="['Only Alphabets and Numbers are allowed.']"
                  [formLabel]="'Name'"
                  [placeholder]="'Enter Name'"
                  [form]="myFormGroup"
          >
          </app-form-field>
        </div>
</form>

我在調用它時遇到了這個錯誤。

ERROR Error: formControlName must be used with a parent formGroup directive.  You'll want to add a formGroup
           directive and pass it an existing FormGroup instance (you can create one in your class).

我認為您忘記在form-field.component.html 中添加 formGroup formGroup

將您的表單域包裝在:

<div [formGroup]="form">
 ...
</div>

如果您想要自定義表單控件,請讓它們從@angular/forms實現ControlValueAccessor

export interface ControlValueAccessor {
  writeValue(obj: any) : void;
  registerOnChange(fn: any) : void;
  registerOnTouched(fn: any) : void;
}

然后將組件注冊到NG_VALUE_ACCESSOR令牌:

  providers: [
    { 
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => MyAwesomeComponent(),
      multi: true
    }
  ]

咆哮:

退后一步,看看你在做什么。 您正在嘗試在表單控件之上構建一個統一層。

您想對文本區域、數字輸入、email 輸入重復此操作嗎? 您打算添加多少條驗證錯誤消息? 他們的 i18n 呢? 而這樣的例子不勝枚舉...

您的代碼不會比您要替換的代碼復雜。

幫自己一個忙,放棄那艘船。

對單個控件使用 formControl="YourFormControlName" 而不是 formControlName。 對於分組控件,您始終需要一個 formGroup 父級。 而且,在使用 formControl 時,您必須添加名稱和 id 屬性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM