web-dev-qa-db-fra.com

Erreur Angular2: Il n'y a pas de directive avec "exportAs" défini sur "ngForm"

je suis sur le RC4 et j'obtiens l'erreur Il n'y a pas de directive avec "exportAs" sur "ngForm" à cause de mon modèle

<div class="form-group">
        <label for="actionType">Action Type</label>
        <select
            ngControl="actionType" 
      ===>  #actionType="ngForm" 
            id="actionType" 
            class="form-control" 
            required>
            <option value=""></option>
            <option *ngFor="let actionType of actionTypes" value="{{ actionType.label }}">
                {{ actionType.label }}
            </option>
        </select> 
    </div>

les boot.ts:

import {disableDeprecatedForms, provideForms} from '@angular/forms'; 

 import {bootstrap} from '@angular/platform-browser-dynamic';
 import {HTTP_PROVIDERS, Http} from '@angular/http';
 import {provideRouter} from '@angular/router';

import {APP_ROUTER_PROVIDER} from './routes';

import {AppComponent} from './app.component';

bootstrap(AppComponent, [ disableDeprecatedForms(), provideForms(), APP_ROUTER_PROVIDER, HTTP_PROVIDERS]);

/// alors voici ma liste déroulante:

<fieldset ngControlGroup="linkedProcess" >
                     <div ngControlGroup="Process" >
                         <label>Linked Process</label>
                          <div class="form-group">       
        <select 
            ngModel
            name="label" 
            #label="ngModel" 
            id="label" 
            class="form-control" required
            (change)="reloadProcesse(list.value)" 
            #list>
            <option value=""></option>
            <!--<option value=`{{ActionFormComponent.getFromString('GET'')}}`></option>-->                 
            <option *ngFor="let processus of linkedProcess?.processList?.list; let i = index" 
            value="{{ processus[i].Process.label}}">
                {{processus.Process.label}}
            </option>
        </select> 
        </div>
     </div>

// mon composant ts:

je le représentais sous les anciennes formes comme ceci: 

 categoryControlGroups:ControlGroup[] = [];
     categories:ControlArray = new ControlArray(this.categoryControlGroups);

et maintenant je fais ça: 

categoryControlGroups:FormGroup[] = [];
     categories:FormArray = new FormArray(this.categoryControlGroups);

vous pensez que c'est la cause du problème ??

80
Anna

Depuis 2.0.0.rc6 :

forms: les fonctions provideForms() et disableDeprecatedForms(), obsolètes, ont été supprimées. Importez plutôt la FormsModule ou la ReactiveFormsModule de @angular/forms.

En bref:

Donc, ajouter à votre app.module.ts ou équivalent:

import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule, ReactiveFormsModule } from '@angular/forms'; // <== add the imports!

import { AppComponent }  from './app.component';

@NgModule({
  imports: [
    BrowserModule,
    FormsModule,                               // <========== Add this line!
    ReactiveFormsModule                        // <========== Add this line!
  ],
  declarations: [
    AppComponent
    // other components of yours
  ],
  bootstrap: [ AppComponent ]
})
export class AppModule { }

Ne pas avoir l'un de ces modules peut entraîner des erreurs, y compris celle que vous rencontrez:

Impossible de se lier à 'ngModel' car ce n'est pas une propriété connue de 'input'.

Impossible de se lier à 'formGroup' car ce n'est pas une propriété connue de 'form'

Il n'y a pas de directive avec "exportAs" défini sur "ngForm"

Si vous avez un doute, vous pouvez fournir les deux la FormsModule et la ReactiveFormsModule ensemble, mais ils sont pleinement fonctionnels séparément. Lorsque vous fournissez l'un de ces modules, les directives de formulaire par défaut et les fournisseurs de ce module seront disponibles pour l'ensemble de l'application. 


Anciens formulaires utilisant ngControl?

Si vous avez ces modules dans votre @NgModule, vous utilisez peut-être d'anciennes directives, telles que ngControl, qui pose problème, car il n'y a pas de ngControl dans les nouveaux formulaires. Il a été remplacé plus ou moins * par ngModel.

Par exemple, l'équivalent de <input ngControl="actionType"> est <input ngModel name="actionType">, changez-le donc dans votre modèle.

De même, l'exportation dans les contrôles n'est plus ngForm, elle est maintenant ngModel. Donc, dans votre cas, remplacez #actionType="ngForm" par #actionType="ngModel".

Le modèle résultant devrait donc être (===>s où modifié):

<div class="form-group">
    <label for="actionType">Action Type</label>
    <select
  ===>  ngModel
  ===>  name="actionType" 
  ===>  #actionType="ngModel" 
        id="actionType" 
        class="form-control" 
        required>
        <option value=""></option>
        <option *ngFor="let actionType of actionTypes" value="{{ actionType.label }}">
            {{ actionType.label }}
        </option>
    </select> 
</div>

* Plus ou moins car toutes les fonctionnalités de ngControl n'ont pas été déplacées vers ngModel. Certains viennent d'être supprimés ou sont différents maintenant. Un exemple est l'attribut name, le cas même que vous avez actuellement.

69
acdcjunior

J'ai fait face au même problème. J'avais manqué la balise d'importation du module de formulaires dans app.module.ts

import { FormsModule } from '@angular/forms';

@NgModule({
    imports: [BrowserModule,
        FormsModule
    ],
55
Chandan

J'ai eu le même problème qui a été résolu en ajoutant le FormsModule au fichier .spec.ts:

import { FormsModule } from '@angular/forms';

puis en ajoutant l'importation à beforeEach:

beforeEach(async(() => {
  TestBed.configureTestingModule({
    imports: [ FormsModule ],
    declarations: [ YourComponent ]
  })
.compileComponents();
}));
9
Juha Ristolainen

Dans mon cas, je devais aussi ajouter FormsModule et ReactiveFormsModule au shared.module.ts

(merci à @Undrium pour l'exemple code ):

import { NgModule }                                 from '@angular/core';
import { CommonModule }                             from '@angular/common';
import { FormsModule, ReactiveFormsModule }         from '@angular/forms';

@NgModule({
  imports:      [
    CommonModule,
    ReactiveFormsModule
  ],
  declarations: [],
  exports: [
    CommonModule,
    FormsModule,
    ReactiveFormsModule
  ]
})
export class SharedModule { }
4
Dirk

Les formes d'utilisation correctes dans Angular2 sont les suivantes:

<form  (ngSubmit)="onSubmit()">

        <label>Username:</label>
        <input type="text" class="form-control"   [(ngModel)]="user.username" name="username" #username="ngModel" required />

        <label>Contraseña:</label>
        <input type="password" class="form-control"  [(ngModel)]="user.password" name="password" #password="ngModel" required />


    <input type="submit" value="Entrar" class="btn btn-primary"/>

</form>

L'ancienne méthode ne fonctionne plus

2
ioses

Nous sommes également conscients que ce problème se pose lorsque nous essayons de combiner des approches de formulaire réactif et de formulaire type. J'avais #name="ngModel" et [formControl]="name" sur le même élément. Supprimer l'un ou l'autre corrigeait le problème. En outre, si vous utilisez #name=ngModel, vous devez également disposer d'une propriété telle que celle-ci [(ngModel)]="name", sinon vous obtiendrez toujours les erreurs. Ceci s'applique également à angular 6, 7 et 8.

0
Samuel Mutemi

Vérifiez que vous avez les deux attributs ngModel and name dans votre sélection. Aussi, Select est un composant de formulaire et non la totalité du formulaire. Une déclaration plus logique de la référence locale sera donc: -

<div class="form-group">
    <label for="actionType">Action Type</label>
    <select
            ngControl="actionType" 
      ===>  #actionType="ngModel"
            ngModel    // You can go with 1 or 2 way binding as well
            name="actionType"
            id="actionType" 
            class="form-control" 
            required>
            <option value=""></option>
            <option *ngFor="let actionType of actionTypes" value="{{ actionType.label }}">
                {{ actionType.label }}
            </option>
        </select> 
    </div>

Une autre chose importante est de vous assurer que vous importez soit FormsModule dans le cas d’une approche utilisant des modèles, soit ReactiveFormsModule dans le cas d’une approche réactive. Ou vous pouvez importer les deux, ce qui est également très bien.

0
Rohan Shenoy

J'ai eu ce problème parce que j'avais une faute de frappe dans mon modèle près de [(ngModel)]]. Support supplémentaire. Exemple:

<input id="descr" name="descr" type="text" required class="form-control width-half"
      [ngClass]="{'is-invalid': descr.dirty && !descr.valid}" maxlength="16" [(ngModel)]]="category.descr"
      [disabled]="isDescrReadOnly" #descr="ngModel">
0
Raman Zhylich

Si vous obtenez ceci à la place:

Erreur: Erreurs d'analyse du modèle: 

Aucune directive pour laquelle "exportAs" a pour valeur "ngModel"

Ce qui était rapporté comme un bogue dans github , alors ce n'est probablement pas un bogue puisque vous pourriez:

  1. vous avez une erreur de syntaxe (par exemple, un crochet supplémentaire: [(ngModel)]]=), OU
  2. be mélange les directives relatives aux formulaires réactifs, telles que formControlName, avec la directive ngModel. Ceci "est obsolète dans Angular v6 et sera supprimé dans Angular v7" , car cela mélange les deux stratégies de forme, ce qui le rend:
  • il semblerait que la directive ngModel soit utilisée, mais en réalité, il s’agit d’une propriété d’entrée/sortie nommée ngModel dans la directive de formulaire réactif qui se rapproche simplement (en partie) de son comportement. Spécifiquement, cela permet d’obtenir/définir la valeur et d’intercepter les événements de valeur. Cependant, certaines des autres fonctionnalités de ngModel - comme retarder les mises à jour avecngModelOptions ou exporter la directive - ne fonctionne tout simplement pas (...)

  • ce modèle mélange des stratégies de formulaires réactives et basées sur des modèles que nous nous ne recommandons généralement pas, car il ne tire pas pleinement parti des avantages des deux stratégies. (...)

  • Pour mettre à jour votre code avant la v7, vous devrez décider si vous souhaitez respecter les directives de formulaire réactives (et obtenir/définir les valeurs à l'aide de modèles de formulaire réactifs) ou basculer vers des directives basées sur des modèles

Quand vous avez une entrée comme celle-ci:

<input formControlName="first" [(ngModel)]="value">

Il affichera un avertissement concernant les stratégies de formulaire mixte dans la console du navigateur:

Il semble que vous utilisiez ngModel dans le même champ de formulaire que formControlName

Toutefois, si vous ajoutez la variable ngModel comme valeur dans une variable de référence, par exemple:

<input formControlName="first" #firstIn="ngModel" [(ngModel)]="value">

L'erreur ci-dessus est alors déclenchée et aucun avertissement concernant le mélange de stratégies n'est affiché.

0
CPHPython