Erreur Angular2: il n'y a pas de directive avec «exportAs» défini sur «ngForm»

109

Je suis sur le RC4 et j'obtiens l'erreur Il n'y a pas de directive avec "exportAs" réglé 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>

le 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]);

/// voici donc 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 dans les anciennes formes comme ceci:

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

et maintenant je fais ceci:

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

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

Anna
la source
Quelle version utilisez-vous? Avez-vous boosté les formulaires?
acdcjunior

Réponses:

98

Depuis 2.0.0.rc6 :

formulaires : obsolètes provideForms()et les disableDeprecatedForms()fonctions ont été supprimées. Veuillez importer le FormsModuleou le ReactiveFormsModulede à la @angular/formsplace.

En bref:

Alors, ajoutez à votreapp.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"

En cas de doute, vous pouvez fournir à la fois le FormsModuleet le ReactiveFormsModuleensemble, mais ils sont entièrement fonctionnels séparément. Lorsque vous fournissez l'un de ces modules, les directives de formulaires par défaut et les fournisseurs de ce module seront disponibles à l'échelle de l'application.


Anciens formulaires utilisant ngControl?

Si vous disposez de ces modules @NgModule, vous utilisez peut-être d'anciennes directives, comme ngControl, ce qui pose problème, car il n'y ngControlen a pas 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">, alors changez cela dans votre modèle.

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

Ainsi, le modèle résultant doit être ( ===>s où changé):

<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 n'ont pas ngControlété déplacées vers ngModel. Certains ont simplement été supprimés ou sont différents maintenant. Un exemple est l' nameattribut, le cas même que vous rencontrez actuellement.

acdcjunior
la source
merci pour votre réponse, quand je l'ai changé, j'ai l'erreur Impossible d'attribuer à une référence ou une variable est-ce que cela vous dit quelque chose?
Anna le
Hmm ... ça peut être ailleurs. En avez-vous à l' <input>intérieur *ngFor? (Ne fonctionnera probablement pas , mais essayer cela et me dire si le message disparaît: <option *ngFor="let actionType of actionTypes; let i = index" value="{{ actionTypes[i].label }}"> {{ actionTypes[i].label }} </option>)
acdcjunior
Avez-vous des <input> dans un *ngFor?
acdcjunior
Essayez de renommer la variable à l'intérieur du *ngForen quelque chose d'autre que actionType, ça va ?
acdcjunior
non je ne le fais pas mais j'ai une liste déroulante de sélection que je suis en train d'itérer, je ne sais pas si c'est la source de l'erreur, veuillez jeter un oeil à ma question mise à jour ...
Anna
61

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

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

@NgModule({
    imports: [BrowserModule,
        FormsModule
    ],
Chandan
la source
2
merci pour cela, cela a bien fonctionné mais devrait-il être app.module.ts pas app.module.component.ts
Salim
Cela ne fonctionne pas pour moi même si j'ai déjà mis l'importation FormsModule dans mon app.module
emirhosseini
9

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

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

puis en ajoutant l'importation à beforeEach:

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

Si vous obtenez plutôt ceci:

Erreur: erreurs d'analyse du modèle:

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

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

  1. avoir une erreur de syntaxe (par exemple un crochet supplémentaire:) [(ngModel)]]=, OU
  2. être mélange directives formes réactives , telles que formControlName, avec la ngModeldirective . Ceci "a été obsolète dans Angular v6 et sera supprimé dans Angular v7" , car cela mélange les deux stratégies de formulaire, ce qui en fait:
  • Il semble que la ngModeldirective réelle soit utilisée, mais en fait c'est une propriété d'entrée / sortie nommée ngModelsur la directive de forme réactive qui se rapproche simplement (d'une partie de) de son comportement. Plus précisément, il permet d'obtenir / définir la valeur et d'intercepter les événements de valeur. Cependant, certaines des ngModelautres fonctionnalités de - comme retarder les mises à jour avec ngModelOptions ou exporter la directive - ne fonctionnent tout simplement pas (...)

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

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

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

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

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

Il semble que vous utilisez ngModelle même champ de formulaire que formControlName.

Cependant, si vous ajoutez le ngModelcomme 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é.

CPHPython
la source
4

Dans mon cas, j'ai dû ajouter FormsModuleet ReactiveFormsModuleà la shared.module.tstrop:

(merci à @Undrium pour l' exemple de 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 { }
Poignard
la source
Cela a résolu mon problème. L'ajouter juste à app.module ne suffisait pas
emirhosseini
3

J'ai eu ce problème et j'ai réalisé que je n'avais pas lié mon composant à une variable.

Modifié

<input #myComponent="ngModel" />

à

<input #myComponent="ngModel" [(ngModel)]="myvar" />

Birwin
la source
2

La bonne façon d'utiliser les formulaires maintenant dans Angular2 est:

<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

ioses
la source
1

Nous avons également réalisé que ce problème se posait lorsque l'on essayait de combiner des approches de formulaire réactif et de formulaire modèle. J'avais #name="ngModel"et [formControl]="name"sur le même élément. La suppression de l'un ou l'autre a résolu le problème. De plus, si vous utilisez, #name=ngModelvous devriez également avoir une propriété comme celle-ci [(ngModel)]="name", sinon, vous obtiendrez toujours les erreurs. Cela s'applique également aux angles 6, 7 et 8.

Samuel Mutemi
la source
0

Vérifiez que vous avez les deux ngModel and nameattributs dans votre sélection. Select est également un composant de formulaire et non le formulaire entier, donc une déclaration plus logique de référence locale sera: -

<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 FormsModuledans le cas d'une approche basée sur un modèle, soit ReactiveFormsModuledans le cas d'une approche réactive. Ou vous pouvez importer les deux, ce qui est également très bien.

Rohan Shenoy
la source
0

si ngModulene fonctionne pas en entrée signifie essayer ... supprimer les guillemetsngModule

comme

<input #form="ngModel" [(ngModel)]......></input>

au lieu d'en haut

<input #form=ngModel [(ngModel)]......></input> try this
user13482587
la source
-1

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">
Raman Zhylich
la source