82 votes

angular2 rc.5 custom input, Pas d'accesseur de valeur pour le contrôle de formulaire avec un nom non spécifié

J'ai un composant d'entrée personnalisé simple comme celui-ci,

import {Component, Provider, forwardRef} from "@angular/core";
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from "@angular/forms";

const noop = () => {};

const CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR: any = {
  provide: NG_VALUE_ACCESSOR,
  useExisting: forwardRef(() => CustomInputComponent),
  multi: true
};

@Component({
  selector: 'custom-input',
  template: `

          <input class="form-control" 
                 [(ngModel)]="value" name="somename"
                 (blur)="onTouched()">

  `,
  providers: [CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR]
})
export class CustomInputComponent implements ControlValueAccessor{

  //The internal data model
  private _value: any = '';

  //Placeholders for the callbacks
  private _onTouchedCallback: () => void = noop;

  private _onChangeCallback: (_:any) => void = noop;

  //get accessor
  get value(): any { return this._value; };

  //set accessor including call the onchange callback
  set value(v: any) {
    if (v !== this._value) {
      this._value = v;
      this._onChangeCallback(v);
    }
  }

  //Set touched on blur
  onTouched(){
    this._onTouchedCallback();
  }

  //From ControlValueAccessor interface
  writeValue(value: any) {
    this._value = value;
  }

  //From ControlValueAccessor interface
  registerOnChange(fn: any) {
    this._onChangeCallback = fn;
  }

  //From ControlValueAccessor interface
  registerOnTouched(fn: any) {
    this._onTouchedCallback = fn;
  }

}

et j'ai un module d'application comme celui-ci,

/**
 * Created by amare on 8/15/16.
 */
import { NgModule }                     from '@angular/core';
import { BrowserModule }                from '@angular/platform-browser';
import { ReactiveFormsModule, FormsModule }          from '@angular/forms';
import { AppComponent }                 from './app/app.component';
import {CustomInputComponent} from "./app/shared/custom.input.component";
import {RouterModule} from "@angular/router";
@NgModule({
  imports: [ BrowserModule, ReactiveFormsModule, FormsModule, RouterModule ],
  declarations: [ AppComponent, CustomInputComponent],
  bootstrap: [ AppComponent ]
})
export class AppModule {  
}

et principal

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule }              from './app.module';

platformBrowserDynamic().bootstrapModule(AppModule);

J'ai utilisé mon entrée personnalisée dans l'un de mes composants comme indiqué ci-dessous, mais je reçois le message "No value accessor for form control with unspecified name attribute".

<custom-input name="firstName" [(ngModel)]="firstName"></custom-input>

et le app.component ressemble à ceci

import { Component } from '@angular/core';

@Component({
  moduleId: module.id,
  selector: 'app-root',
  templateUrl: 'app.component.html',
  styleUrls: ['app.component.css']
})
export class AppComponent {
  title = 'app works!';

  firstName: string;
}

0 votes

J'ai le même problème avec une directive personnalisée qui implémente ControlValueAccessor. Elle fonctionnait dans la RC4 mais obtient la même erreur que vous dans la RC5. J'espère que quelqu'un a une solution.

39 votes

Essayez d'ajouter ngDefaultControl à votre contrôle, comme ceci : <custom-input name="firstName" [(ngModel)]="firstName" ngDefaultControl></custom-input>

0 votes

@danieleds merci beaucoup cela fonctionne comme un charme, même si l'équipe angular ne répondait pas.

74voto

Amare Points 1054

L'ajout de ngDefaultControl au composant d'entrée personnalisé dans l'hôte a résolu le problème, merci @danieleds

9 votes

Cette solution n'a pas fonctionné pour moi. J'ai un nom appliqué à mon input et j'ai aussi essayé d'ajouter ngDefaultControl à l'entrée et cela n'a pas fonctionné. J'ai toujours eu la même erreur. Dans la RC5

2 votes

D'accord, j'ai ajouté la propriété name dans le html et ngDefaultControl et j'utilise formControl et ça ne marche pas.

1 votes

Voir une très bonne explication sur la façon dont ngDefaultControl travaille - stackoverflow.com/a/46465959/968003 . Essentiellement, il ajoute par défaut ControlValueAccessor qui agit comme un pont entre l'API des formulaires Angular et un élément natif dans le DOM.

46voto

Nick Points 594

Ajoutez ngDefaultControl au composant de saisie personnalisé. Cela ajoute une liaison de données bidirectionnelle. Vous ne devriez pas avoir à mettre en œuvre les méthodes d'accès aux valeurs, sauf si vous faites quelque chose d'unique.

<custom-input name="firstName" [(ngModel)]="firstName" ngDefaultControl></custom-input>

13voto

Ajouter ngDefaultControl à votre contribution. eg

<inline-editor type="textarea" [(ngModel)]="editableTextArea" (onSave)="saveEditable($event)" value="valor" ngDefaultControl> </inline-editor> 

Puis import { FORM_DIRECTIVES } from '@angular/common' ;

Enfin, les directives : [FORM_DIRECTIVES]

Cela va fonctionner :) Merci pour les commentaires ci-dessus

2 votes

Veuillez utiliser les backticks et autres markdown pour rendre votre message plus lisible.

4 votes

J'utilise la RC6 et il n'y a pas de FORM_DIRECTIVES en @angular/common

6 votes

LES DIRECTIVES DE FORME NE SONT PLUS AVEC NG2 FINAL

4voto

ryan knell Points 192

Je mettais [(ngModel)] sur mon <option> au lieu de <select>

Donc oui... ça va causer ça.

0voto

bsplosion Points 79

Comme un autre scénario où cela se produit, j'avais [(ngModel)] spécifié sur un composant personnalisé qui a été récemment reconstruit et simplifié, et la nouvelle version du composant vient d'avoir ngModel comme une variable d'entrée normale avec des emits.

Ce n'était pas suffisant - la variable d'entrée doit être renommée en quelque chose d'autre que ngModel ou le composant doit mettre en œuvre l'option ControlValueAccessor interface ( voir la documentation pour plus de détails ). Une fois l'un ou l'autre terminé, vous n'obtiendrez plus cette erreur.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X