繁体   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