ERROR Error: Nenhum acessador de valor para controle de formulário com atributo de nome não especificado na chave


104

Aqui está meu componente no 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>
    `
} )

Aqui está minha aula:

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;
    }
}

Este é o erro que recebo ao compilar:

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)

Quando eu mudo o elemento switch para input ele funciona, sabendo que estou usando a mesma estrutura para outros componentes e funciona bem.



Isso provavelmente pode ajudá-lo: stackoverflow.com/questions/46708080/…
Dinistro,

Respostas:


155

Corrigi esse erro adicionando os name="fieldName" ngDefaultControlatributos ao elemento que carrega o [(ngModel)]atributo.


34
Alguma explicação adicional tornaria essa resposta melhor. Onde você encontrou documentação de ngDefaultControl, por exemplo?
isherwood

16
Acho que name="fieldname"não é necessário, mas ngDefaultControlresolve o problema.
michaeak de


Adicionar "ngDefaultControl" (no atributo com a diretiva * ngFor) resolveu meu problema semelhante.
Davidson Lima,

2
para mim, resolvi isso importando o pacote do módulo para um elemento usado no grupo de formulários (por exemplo, AngularEditorModule) para reconhecer o controle no modelo e ngDefaultControl será capaz de acessá-lo. Eu descobri enquanto fazia um teste de unidade.
aj go

101

Eu tive o mesmo problema e o problema era que meu componente filho tinha um @inputnome formControl.

Então, eu só precisava mudar de:

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

para:

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

ts:

@Input()
control:FormControl;

1
Funciona com Angular 10, como dito em um comentário anterior, é realmente difícil rastrear este, no entanto, depois, faz sentido que "formControl" não deva ser usado como um nome de propriedade @Input do componente devido a um conflito de namespace potencial , outra solução de nomenclatura poderia ser renomear o campo _formControl, que é alimentado por uma instância de FormControl.
Thomas,

41

Também recebi este erro ao escrever um componente de controle de formulário personalizado no Angular 7. No entanto, nenhuma das respostas se aplica ao Angular 7.

No meu caso, o seguinte precisava ser adicionado ao @Componentdecorador:

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

Este é um caso de "Não sei por que funciona, mas funciona." Atribui a má concepção / implementação por parte da Angular.


6
Este trecho diz à camada de injeção de dependência do Angular que sua classe deve ser retornada quando outras classes (ou seja, a diretiva formControlName) solicitam o token NG_VALUE_ACCESSOR. Sem ele, o angular não teria como saber que sua classe é um controle de formulário personalizado (todas as informações sobre interfaces, etc. são retiradas durante a transpilação)
Max Mumford

20

Eu também tive o mesmo erro, angular 7

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

Acabei de adicionar ngDefaultControl

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


8

Eu tive este mesmo erro - acidentalmente vinculei [(ngModel)] ao meu em mat-form-fieldvez do inputelemento.


7

Eu estava recebendo essa mensagem de erro em meus testes de unidade com Jasmine. Eu adicionei o atributo ngDefaultControl ao elemento personalizado (no meu caso, era um botão deslizante angular de material) e isso resolve o erro.

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

Altere o elemento acima para incluir o atributo ngDefaultControl

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

6

Eu estava enfrentando este erro ao executar casos de teste de unidade Karma. Adicionar MatSelectModule nas importações corrige o problema

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

Somente se você tiver "Angular Material" instalado, caso contrário, você não precisa disso.
Mikefox2k

6

Isso é meio estúpido, mas recebi essa mensagem de erro usando acidentalmente em [formControl]vez de [formGroup]. Veja aqui:

ERRADO

@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: ''
    })
  }
}

DIREITO

@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

No meu caso, inseri [(ngModel)] no rótulo em vez de na entrada. Também há uma ressalva, tentei executar corretamente o erro acima na linha especificada, mas o erro não foi. Se houver outros lugares onde você cometeu o mesmo erro, ele ainda lançará o mesmo erro na mesma linha


1
Esta é uma boa resposta. Alguns componentes (select, rádio, etc) você pode escorregar e colocar o ngModel no lugar errado como este. A mensagem de erro não ajuda muito.
AndrewBenjamin

3

No meu caso usei diretiva, mas não importei no meu arquivo module.ts. O Import corrigiu isso.


Obrigado, mas eu também precisava reiniciar ng servepara atualizar a importação
FindOutIslamNow

2

Eu tive esse mesmo erro, eu tinha um campo de entrada chamado controlem meu componente de formulário personalizado, mas estava passando o controle acidentalmente na entrada chamada formControl. Espero que ninguém enfrente esse problema.


2

No meu caso foi tão idiota quanto registrar o novo componente para DI nas minhas app.module.tsdeclarações mas não nas exportações.


2

No meu caso, está acontecendo no meu módulo compartilhado e tive que adicionar o seguinte em @NgModule:

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

2

Também recebi esse erro quando nomeei uma das entradas do meu componente como 'formControl'. Provavelmente está reservado para outra coisa. Se você deseja passar o objeto FormControl entre componentes, use-o assim:

@Input() control: FormControl;

Assim não:

@Input() formControl: FormControl;

Estranho - mas funcionando :)


0

Tive o mesmo erro, mas no meu caso aparentemente foi um problema de sincronização, no momento de renderizar os componentes html.

Segui algumas das soluções propostas nesta página, mas qualquer uma delas funcionou para mim, pelo menos não completamente.

O que realmente resolveu meu erro foi escrever o trecho de código abaixo dentro da tag html pai dos elementos.

Eu estava vinculado à variável.

Código:

    *ngIf="variable-name"

O erro foi causado, aparentemente pelo projeto tentando renderizar a página, aparentemente no momento de avaliar a variável, o projeto simplesmente não conseguiu encontrar o seu valor. Com o trecho de código acima, você se certifica de que, antes de renderizar a página, pergunte se a variável foi inicializada.

Este é meu código 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));
    });
  }
      ...

Aqui está minha marcação 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">
             ...

Espero que isso possa ser útil.


este link tem um problema semelhante :, stackoverflow.com/q/49409674/8992452 talvez possa ajudar com o problema
NUKE

0

Você já tentou mover seu [(ngModel)]para o em divvez de switchno seu HTML? O mesmo erro apareceu no meu código porque vinculei o modelo a a em <mat-option>vez de a <mat-select>. Embora eu não esteja usando o controle de formulário.


0

No meu caso, era um componente.membro que não existia, por exemplo

[formControl]="personId"

Adicioná-lo à declaração da classe corrigiu-o

this.personId = new FormControl(...)

0

No meu caso, o erro foi desencadeado pela duplicação de uma importação de um componente no módulo.


0

#Fundo

  • NativeScript 6.0

No meu caso, o erro foi disparado pela alteração da tag do elemento de para por falha. Dentro de <TextView an [(ngModel)] = "nome". foi definido.

Depois de remover [(ngModel)] = o erro "nome" desapareceu.


0

Eu estava enfrentando esse problema durante a execução de testes de unidade. Para corrigir, adicionei o MatSlideToggleModule às importações em meu arquivo spect.ts.


-1

no meu caso, eu tinha uma <TEXTAREA>tag do antigo html durante a conversão para angular. Tive que mudar para <textarea>.


Eu não votei negativamente, mas essa NUNCA deve ser a causa.
FindOutIslamNow

-1

Este erro também ocorre se você tentar adicionar ngModel aos elementos que não são de entrada, como opções suspensas ou de botão de rádio. No meu caso, adicionei um ngModel à opção ion-select em vez de ion-select.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.