错误错误:表单控件的无值访问器在开关上具有未指定的名称属性


104

这是我在Angular 4中的组件:

@Component( {
    selector: 'input-extra-field',
    template: `
            <div class="form-group" [formGroup]="formGroup" >
                <switch [attr.title]="field.etiquette" 
                    [attr.value]="field.valeur" [(ngModel)]="field.valeur"
                    [formControl]="fieldControl" [attr.id]="name" [attr.disabled]="disabled">
                </switch>
                <error-messages [control]="name"></error-messages>
            </div>
    `
} )

这是我的课:

export class SwitchExtraField extends ExtraField {
    @Input() field: ExtraFormField;
    @Input() entity: { fields: Object };
    @Input() formGroup: FormGroup;

    constructor( formDir: NgForm ) {
        super( null, null, formDir );
    }

    get disabled(): string {
        if ( this.field && !!this.field.saisissable && !this.field.saisissable )     {
            return 'disabled';
        }
        return null;
    }
}

这是我在编译时遇到的错误:

ERROR Error: No value accessor for form control with unspecified name attribute
    at _throwError (forms.es5.js:1918)
    at setUpControl (forms.es5.js:1828)
    at FormControlDirective.webpackJsonp.../../../forms/@angular/forms.es5.js.FormControlDirective.ngOnChanges (forms.es5.js:4617)

当我将元素开关更改为输入时,它知道我对其他组件使用了相同的结构,并且可以正常工作。



Answers:


155

我通过将name="fieldName" ngDefaultControl属性添加到带有[(ngModel)]属性的元素中来解决了该错误。


34
一些其他解释将使这成为一个更好的答案。ngDefaultControl例如,您在哪里找到的文档?
isherwood

16
我认为name="fieldname"没有必要,但是ngDefaultControl可以解决问题。
michaeak


添加“ ngDefaultControl”(在带有* ngFor指令的属性上)解决了我类似的问题。
戴维森·利马

2
对我来说,我通过导入用于表单组中的元素的模块包(例如AngularEditorModule)来识别模板中的控件,从而修复了此问题,ngDefaultControl可以访问它。我在进行单元测试时发现了它。
aj去

101

我遇到了同样的问题,问题在于我的子组件有一个@inputnamed formControl

所以我只需要更改以下内容:

<my-component [formControl]="formControl"><my-component/>

至:

<my-component [control]="control"><my-component/>

ts:

@Input()
control:FormControl;

1
如上一则评论所述,它可以与Angular 10一起使用,很难找到它,但是之后,由于潜在的名称空间冲突,不应将“ formControl”用作组件@Input属性名,另一个命名解决方案是重命名由FormControl实例提供的_formControl字段。
托马斯

41

在Angular 7中编写自定义表单控件组件时,我也收到此错误。但是,所有答案都不适用于Angular 7。

就我而言,需要将以下内容添加到@Component装饰器中:

  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => MyCustomComponent),  // replace name as appropriate
      multi: true
    }
  ]

这是“我不知道为什么起作用,但确实起作用”的情况。总结一下Angular的不良设计/实现。


6
此代码段告诉Angular的依赖项注入层,当其他类(即formControlName指令)向其请求令牌NG_VALUE_ACCESSOR时,应返回您的类。如果没有它,angular将无法得知您的课程是自定义表单控件(有关所有接口等的信息,在移植过程中会被删除)
Max Mumford

20

我也有同样的错误,角度7

 <button (click)="Addcity(city.name)" [(ngModel)]="city.name"  class="dropdown-item fontstyle"
     *ngFor="let city of Cities; let i = index">
      {{city.name}}
 </button>

我刚刚添加了 ngDefaultControl

   <button (click)="Addcity(city.name)" [(ngModel)]="city.name"  ngDefaultControl class="dropdown-item fontstyle"
 *ngFor="let city of Cities; let i = index">
  {{city.name}}



7

我在使用Jasmine进行单元测试时收到此错误消息。我向自定义元素添加了ngDefaultControl属性(在我的情况下,这是一个有角度的材质滑动切换),这可以解决该错误。

<mat-slide-toggle formControlName="extraCheese">
  Extra Cheese
</mat-slide-toggle>

更改以上元素以包括ngDefaultControl属性

<mat-slide-toggle ngDefaultControl formControlName="extraCheese">
 Extra Cheese
</mat-slide-toggle>

6

我在运行业力单元测试用例时遇到此错误,在导入中添加MatSelectModule可解决此问题

imports: [
        HttpClientTestingModule,
        FormsModule,
        MatTableModule,
        MatSelectModule,
        NoopAnimationsModule
      ],

仅当您安装了“ Angular Material”时,否则就不需要它。
Mikefox2k

6

这是一种愚蠢的行为,但是我偶然使用[formControl]而不是来得到此错误消息[formGroup]。看这里:

错误

@Component({
  selector: 'app-application-purpose',
  template: `
    <div [formControl]="formGroup"> <!-- '[formControl]' IS THE WRONG ATTRIBUTE -->
      <input formControlName="formGroupProperty" />
    </div>
  `
})
export class MyComponent implements OnInit {
  formGroup: FormGroup

  constructor(
    private formBuilder: FormBuilder
  ) { }

  ngOnInit() {
    this.formGroup = this.formBuilder.group({
      formGroupProperty: ''
    })
  }
}

@Component({
  selector: 'app-application-purpose',
  template: `
    <div [formGroup]="formGroup"> <!-- '[formGroup]' IS THE RIGHT ATTRIBUTE -->
      <input formControlName="formGroupProperty" />
    </div>
  `
})
export class MyComponent implements OnInit {
  formGroup: FormGroup

  constructor(
    private formBuilder: FormBuilder
  ) { }

  ngOnInit() {
    this.formGroup = this.formBuilder.group({
      formGroupProperty: ''
    })
  }
}

5

就我而言,我在标签而不是输入上插入了[[ngModel)]。还有一个警告,我尝试在指定的行中正确地执行上述错误后运行,但该错误不会消失。如果在其他地方您犯了相同的错误,它仍然会在同一行上引发相同的错误


1
这是一个很好的答案。您可以像这样将某些组件(选择,广播等)滑倒并将ngModel粘贴在错误的位置。该错误消息没有太大帮助。
AndrewBenjamin

3

就我而言,我使用了指令,但是没有将其导入我的module.ts文件中。导入修复它。


谢谢,但我还需要重新启动ng serve才能刷新导入
FindOutIslamNow

2

我遇到了同样的错误,我control在自定义Form Component中有一个输入字段,但是意外地将控制传递给了名为的输入formControl。希望没人面对这个问题。


2

在我的情况下,它是为愚蠢的已经登记为DI新组件在我的app.module.ts声明,而不是出口。


2

就我而言,这是在我的共享模块中发生的,我必须在@NgModule中添加以下内容:

...
  imports: [
    CommonModule,
    FormsModule,
    ReactiveFormsModule,
    IonicModule
  ],
...

2

当我将一个组件输入命名为“ formControl”时,我也收到此错误。可能是为其他东西保留的。如果要在组件之间传递FormControl对象,请像这样使用它:

@Input() control: FormControl;

不像这样:

@Input() formControl: FormControl;

很奇怪-但是工作:)


0

我遇到了同样的错误,但就我而言,在呈现组件html时,这显然是一个同步问题。

我遵循了本页上提出的一些解决方案,但是其中任何一个对我都有效,至少不是完全有效。

实际上解决我的错误的方法是在元素的父html标签内编写以下代码段。

我绑定到变量。

码:

    *ngIf="variable-name"

该错误是由项目试图渲染页面引起的,显然是在评估变量时,该项目无法找到其值。使用上面的代码片段,您可以确保在呈现页面之前,询问变量是否已初始化。

这是我的component.ts代码:

import { Component, OnInit } from '@angular/core';
import { InvitationService } from 'src/app/service/invitation.service';
import { BusinessService } from 'src/app/service/business.service';
import { Invitation } from 'src/app/_models/invitation';
import { forEach } from '@angular/router/src/utils/collection';

@Component({
  selector: 'app-invitation-details',
  templateUrl: './invitation-details.component.html',
  styleUrls: ['./invitation-details.component.scss']
})
export class InvitationDetailsComponent implements OnInit {
  invitationsList: any;
  currentInvitation: any;
  business: any;
  invitationId: number;
  invitation: Invitation;

  constructor(private InvitationService: InvitationService, private BusinessService: 
BusinessService) { 
this.invitationId = 1; //prueba temporal con invitacion 1
this.getInvitations();
this.getInvitationById(this.invitationId);
  }

   ngOnInit() {

  }

  getInvitations() {
    this.InvitationService.getAllInvitation().subscribe(result => {
      this.invitationsList = result;
      console.log(result);
    }, error => {
      console.log(JSON.stringify(error));
    });
  }

  getInvitationById(invitationId:number){
    this.InvitationService.getInvitationById(invitationId).subscribe(result => {
      this.currentInvitation = result;
      console.log(result);
      //this.business=this.currentInvitation['business'];
       //console.log(this.currentInvitation['business']); 
     }, error => {
     console.log(JSON.stringify(error));
    });
  }
      ...

这是我的html标记:

<div class="container-fluid mt--7">
  <div class="row">
    <div class="container col-xl-10 col-lg-8">
      <div class="card card-stats ">
        <div class="card-body container-fluid form-check-inline" 
         *ngIf="currentInvitation">
          <div class="col-4">
             ...

我希望这会有所帮助。


该链接有一个类似的问题:stackoverflow.com/q/49409674/8992452也许可以解决这个问题
NUKE,

0

您是否尝试过移动你[(ngModel)]div,而不是switch在你的HTML?我的代码中出现了相同的错误,这是因为我将模型绑定到<mat-option>而不是<mat-select>。虽然我没有使用窗体控件。




0

#背景

  • NativeScript 6.0

在我的情况下,错误是由错误将元素标签从更改为触发的。在<TextView内部,一个[(ngModel)] =“ name”。被定义。

删除[(ngModel)] =“ name”后,错误消失了。


0

我在运行单元测试时遇到了这个问题。为了解决这个问题,我将MatSlideToggleModule添加到了spect.ts文件中的导入中。


-1

在我的情况下,我<TEXTAREA>在转换为角度时有一个来自旧html的标签。不得不改为<textarea>


我没有投票,但这绝对不是原因。
FindOutIslamNow

-1

如果您尝试将ngModel添加到非输入元素(例如下拉列表或单选按钮选项),也会发生此错误。就我而言,我将ngModel添加到ion-select-option而不是ion-select中。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.