错误错误:交换机上没有指定名称属性的表单控件没有值访问器

Sue*_*Sue 36 form-control angular

我是angular4的新手,这是我的组件:

@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>
    `
} )
Run Code Online (Sandbox Code Playgroud)

这是我的班级:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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)
Run Code Online (Sandbox Code Playgroud)

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

谢谢.

Pie*_*ini 59

我通过将name="fieldName" ngDefaultControl属性添加到包含该[(ngModel)]属性的元素来修复此错误.

  • 我认为 `name="fieldname"` 不是必需的,但 `ngDefaultControl` 可以解决这个问题。 (26认同)
  • 更多解释在这里。/sf/ask/3252612401/ (9认同)
  • 一些其他解释将使这成为一个更好的答案。例如,您在哪里找到ngDefaultControl的文档? (6认同)
  • 对我来说,我通过导入表单组中使用的元素的模块包(例如 AngularEditorModule)来修复此问题,以识别模板中的控件,并且 ngDefaultControl 将能够访问它。我在进行单元测试时发现了它。 (5认同)

Edu*_*gas 26

我遇到了同样的问题,问题是我的子组件有一个@input具名的formControl

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

<my-component [formControl]="formControl"><my-component/>
Run Code Online (Sandbox Code Playgroud)

至:

<my-component [control]="control"><my-component/>
Run Code Online (Sandbox Code Playgroud)

ts:

@Input()
control:FormControl;
Run Code Online (Sandbox Code Playgroud)

  • 巨大的救星!谢谢,很难找到这个。 (5认同)
  • 与 Angular 10 一起使用,正如之前的评论中所说,很难找到这个,但是,之后,由于潜在的命名空间冲突,“formControl”不应该用作组件 @Input 属性名称是有道理的,另一个命名解决方案可能是重命名由 FormControl 实例提供的字段 _formControl 。 (3认同)
  • 我的上帝。2.... 小时.... 伙计.... 试图修复它.... 2 .... 小时........ 我希望 Angular 警告我放置 `@Input() formControl` 不是一个好主意:D (3认同)
  • 面临同样的问题 (2认同)

the*_*yer 22

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

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

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

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

  • 这段代码告诉 Angular 的依赖注入层,当其他类(即 formControlName 指令)向它请求令牌 NG_VALUE_ACCESSOR 时,应该返回你的类。如果没有它,Angular 将无法知道您的类是自定义表单控件(有关接口等的所有信息在转译过程中都会被删除) (9认同)

Sam*_*sil 16

当您在不能像元素一样具有值的元素上使用 ngModel 或 formControl 时,就会发生这种情况<div>

像这样使用 ngModel 或 formControl 时会出现问题:

<div [(ngModel)]="myModel"> <--- wrong place
    <input type="text" />
</div>
Run Code Online (Sandbox Code Playgroud)

解决方案:

<div>
    <input type="text" [(ngModel)]="myModel" /> <--- correct place
</div>
Run Code Online (Sandbox Code Playgroud)

来源:https ://github.com/angular/angular/issues/43821#issuecomment-992305494


Dan*_*til 10

我在运行 Karma 单元测试用例时遇到了这个错误在导入中添加MatSelectModule修复了这个问题

imports: [
        HttpClientTestingModule,
        FormsModule,
        MatTableModule,
        MatSelectModule,
        NoopAnimationsModule
      ],
Run Code Online (Sandbox Code Playgroud)

  • 仅当您安装了“Angular Material”时,否则您不需要它。 (2认同)
  • 我想补充一点,这适用于 Angular Material 中的任何“输入”元素。例如,我有一个带有表单控件的 Slide Toggle 元素,在运行 Karma 测试时它给了我“无值访问器”错误。结果,我必须将 MatSlideToggleModule 导入添加到我的“spec.ts”类中才能让它识别输入。 (2认同)

Sud*_*han 9

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

<mat-slide-toggle formControlName="extraCheese">
  Extra Cheese
</mat-slide-toggle>
Run Code Online (Sandbox Code Playgroud)

更改上述元素以包含ngDefaultControl属性

<mat-slide-toggle ngDefaultControl formControlName="extraCheese">
 Extra Cheese
</mat-slide-toggle>
Run Code Online (Sandbox Code Playgroud)


Nad*_*smi 8

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

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

我刚刚添加了 ngDefaultControl

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


Chr*_*gen 8

我有同样的错误 - 我不小心将 [(ngModel)] 绑定到我的mat-form-field而不是input元素。


Tre*_*vor 7

这有点愚蠢,但我不小心使用[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: ''
    })
  }
}
Run Code Online (Sandbox Code Playgroud)

@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: ''
    })
  }
}
Run Code Online (Sandbox Code Playgroud)


小智 7

就我而言,我忘记添加providers: [INPUT_VALUE_ACCESSOR]到我的自定义组件中

我将 INPUT_VALUE_ACCESSOR 创建为:

export const INPUT_VALUE_ACCESSOR = {
  provide: NG_VALUE_ACCESSOR,
  useExisting: forwardRef(() => TextEditorComponent),
  multi: true,
};
Run Code Online (Sandbox Code Playgroud)


And*_*ris 6

在我的例子中,我使用了指令,但没有在我的 module.ts 文件中导入它。导入修复了它。


小智 6

我在 mat-select 中使用了 formControl,如下所示:

<mat-select [formControl]="control">
 ...
</mat-select>
Run Code Online (Sandbox Code Playgroud)

我意识到 MatSelectModule 没有导入到规范文件中,这解决了问题。


小智 5

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


Pei*_*Pei 5

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

...
  imports: [
    CommonModule,
    FormsModule,
    ReactiveFormsModule,
    IonicModule
  ],
...
Run Code Online (Sandbox Code Playgroud)


小智 5

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

@Input() control: FormControl;
Run Code Online (Sandbox Code Playgroud)

不是这样的:

@Input() formControl: FormControl;
Run Code Online (Sandbox Code Playgroud)

奇怪 - 但工作:)


San*_*ndy 5

如果您尝试将 ngModel 添加到非输入元素(如<option>HTML 标签),也会发生此错误。确保仅将 ngModel 添加到<input>标签中。就我而言,我已将 ngModel 添加到<ion-select-option>而不是<ion-select>.


Moo*_*way 5

就我而言,问题是我创建了一个@Input保留名称的变量formControl


小智 5

看起来“formControl”是 Angular Forms 的保留名称,当我使用这个名称作为组件的输入时,我的实际控制出现了意外的行为。如果你问我,我会说这是一个 Angular 错误。只需将您的输入名称替换为其他名称,例如“frmCtrl”或其他名称,它就会起作用。