简体   繁体   English

Angular - 表单内的组件 - formControlName 必须与父级一起使用

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

I wanted to reuse a single component to dynamically generate form input fields and came up with this code我想重用单个组件来动态生成表单输入字段并想出了这段代码

form-field.component.html 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 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;
  }

parent-component.html父组件.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>

And I'm getting this error while calling it.我在调用它时遇到了这个错误。

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).

I think you forgot to add formGroup in form-field.component.html .我认为您忘记在form-field.component.html 中添加 formGroup formGroup

Wrap your form-field in:将您的表单域包装在:

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

If you want to have custom form controls, make them implement ControlValueAccessor from @angular/forms .如果您想要自定义表单控件,请让它们从@angular/forms实现ControlValueAccessor

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

Then register the components to the NG_VALUE_ACCESSOR token:然后将组件注册到NG_VALUE_ACCESSOR令牌:

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

Rant:咆哮:

Take a step back and look at what you are doing.退后一步,看看你在做什么。 You are trying to build a unifying layer above form controls.您正在尝试在表单控件之上构建一个统一层。

Do you want to repeat this for textareas, number inputs, email inputs...?您想对文本区域、数字输入、email 输入重复此操作吗? How many validation error messages do you plan to add?您打算添加多少条验证错误消息? What about their i18n?他们的 i18n 呢? And the list goes on...而这样的例子不胜枚举...

Your code will be no less complex than what you are trying to replace.您的代码不会比您要替换的代码复杂。

Do yourself a favor, abandon that ship.帮自己一个忙,放弃那艘船。

Use a formControl="YourFormControlName" instead of formControlName for single control.对单个控件使用 formControl="YourFormControlName" 而不是 formControlName。 For grouped controls, you always need a formGroup parent.对于分组控件,您始终需要一个 formGroup 父级。 And, when using formControl, you have to add a name and id attribute.而且,在使用 formControl 时,您必须添加名称和 id 属性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Angular pipe 与 angular 表单数组的反应 formControlName - Angular pipe with reactive formControlName of angular form array Angular 8:在内部组件中实现 formControlName - Angular 8: Implement formControlName inside Inner Component 带有父/子组件的Angular 2/4管理表单CRUD - Angular 2/4 managing form CRUD with parent/child components Angular:ControlValueAccessor更新到共享相同formControlName的所有组件 - Angular: ControlValueAccessor update to all components who share same formControlName Angular 7:在角度反应形式中找不到名称为 formControlName 的控件 - Angular 7: Cannot find control with name: formControlName in angular reactive form Angular 8:组件内部的formControlName下面有多个嵌套级别 - Angular 8: formControlName inside component multiple nested levels below Angular 8:组件内部的 formControlName,使用 formgroupname 替代 ControlValueAccessor 等? - Angular 8: formControlName inside component, Alternative to ControlValueAccessor with formgroupname, etc? Angular表单提交事件在父组件和子组件之间触发两次 - Angular form submit event firing twice between parent and child components Angular:仅一种形式的多个字段ControlName,反应形式 - Angular: multiple fields in just one formControlName, reactive form Angular formControlName - 反应形式 - 将值设置为 primeNg p-dropdown - Angular formControlName - reactive form - Setting values to primeNg p-dropdown
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM