Errore Angular2: non esiste alcuna direttiva con "exportAs" impostato su "ngForm"


109

sono sull'RC4 e ricevo l'errore Non esiste alcuna direttiva con "exportAs" impostato su "ngForm" a causa del mio modello:

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

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

/// quindi ecco il mio elenco a discesa:

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

// il mio componente ts:

lo stavo rappresentando nelle vecchie forme come questa:

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

e ora sto facendo questo:

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

pensi che sia la causa del problema?


Quale versione stai usando? Hai potenziato le forme?
acdcjunior

Risposte:


98

Dalla 2.0.0.rc6 :

moduli : deprecato provideForms()e le disableDeprecatedForms()funzioni sono state rimosse. Si prega di importare invece il FormsModuleo il ReactiveFormsModuleda @angular/forms.

In breve:

Quindi, aggiungi al tuoapp.module.ts o equivalente:

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

Non avere uno di questi moduli può portare a errori, incluso quello che devi affrontare:

Impossibile eseguire il binding a "ngModel" poiché non è una proprietà nota di "input".

Impossibile eseguire il binding a "formGroup" poiché non è una proprietà nota di "form"

Non esiste alcuna direttiva con "exportAs" impostato su "ngForm"

In caso di dubbio, è possibile fornire sia il FormsModuleche il ReactiveFormsModuleinsieme, ma sono completamente funzionanti separatamente. Quando fornisci uno di questi moduli, le direttive dei moduli predefinite e i provider di quel modulo saranno disponibili per tutta l'app.


Vecchi moduli utilizzando ngControl?

Se hai quei moduli a portata di mano @NgModule, forse stai usando vecchie direttive, come ngControl, che è un problema, perché non ce ne sono ngControlnei nuovi moduli. È stato sostituito più o meno * da ngModel.

Ad esempio, l'equivalente di <input ngControl="actionType">è <input ngModel name="actionType">, quindi cambialo nel tuo modello.

Allo stesso modo, l'esportazione nei controlli non è ngFormpiù, è adesso ngModel. Quindi, nel tuo caso, sostituisci #actionType="ngForm"con #actionType="ngModel".

Quindi il modello risultante dovrebbe essere ( ===>se modificato):

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

* Più o meno perché non tutte le funzionalità di sono ngControlstate spostate a ngModel. Alcuni sono stati rimossi o sono diversi ora. Un esempio è l' nameattributo, proprio il caso che hai in questo momento.


grazie per la tua risposta, quando l'ho modificata ho l'errore Impossibile assegnare un riferimento o una variabile ti dice qualcosa ??
Anna

Hmm .. potrebbe essere da qualche altra parte. Ne hai <input>dentro un *ngFor? (Probabilmente non funzionerà, ma provate questo e dimmi se il messaggio va via: <option *ngFor="let actionType of actionTypes; let i = index" value="{{ actionTypes[i].label }}"> {{ actionTypes[i].label }} </option>)
acdcjunior

Hai qualche <input> all'interno di un *ngFor?
acdcjunior

Prova a rinominare la variabile all'interno *ngFordi qualcosa di diverso da actionType, va bene?
acdcjunior

no, ma ho un elenco a discesa di selezione che sto iterando non so se è la fonte dell'errore, per favore dai un'occhiata alla mia domanda aggiornata ...
Anna

61

Ho affrontato lo stesso problema. Avevo perso il tag di importazione del modulo dei moduli in app.module.ts

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

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

2
grazie per questo, ha funzionato bene ma dovrebbe essere app.module.ts non app.module.component.ts
Salim

Questo non funziona per me anche se ho già inserito l'importazione di FormsModule nella mia app.module
emirhosseini

9

Ho avuto lo stesso problema che è stato risolto aggiungendo FormsModule a .spec.ts:

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

e quindi aggiungendo l'importazione a beforeEach:

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

5

Se invece ricevi questo:

Errore: errori di analisi del modello:

Non esiste alcuna direttiva con "exportAs" impostato su " ngModel "

Che è stato segnalato come un bug in GitHub , quindi probabilmente non è un bug poiché potresti:

  1. hanno un errore di sintassi (ad esempio una parentesi aggiuntiva :) [(ngModel)]]=, OR
  2. essere mescolando forme direttive reattivi , come ad esempio formControlName, con la ngModeldirettiva . Questo "è stato deprecato in Angular v6 e sarà rimosso in Angular v7" , poiché questo mescola entrambe le strategie del modulo, rendendolo:
  • sembra che ngModelvenga utilizzata la direttiva effettiva , ma in realtà è una proprietà di input / output denominata ngModelsulla direttiva del modulo reattivo che si avvicina semplicemente (alcuni) al suo comportamento. In particolare, consente di ottenere / impostare il valore e di intercettare eventi di valore. Tuttavia, alcune delle ngModelaltre funzionalità , come ritardare gli aggiornamenti con ngModelOpzioni o esportare la direttiva, semplicemente non funzionano (...)

  • questo modello mescola strategie basate su modelli e forme reattive, che generalmente non consigliamo perché non sfrutta appieno i vantaggi di nessuna delle due strategie . (...)

  • Per aggiornare il codice prima della v7, ti consigliamo di decidere se attenersi alle direttive del modulo reattivo (e ottenere / impostare valori utilizzando modelli di moduli reattivi) o passare alle direttive guidate dal modello .

Quando hai un input come questo:

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

Mostrerà un avviso sulle strategie di form miste nella console del browser:

Sembra che tu stia utilizzando ngModelnello stesso campo modulo di formControlName.

Tuttavia, se aggiungi ngModelcome valore in una variabile di riferimento, ad esempio:

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

L'errore di cui sopra viene quindi attivato e non viene visualizzato alcun avviso sulla combinazione di strategie.


4

Nel mio caso ho dovuto aggiungere FormsModulee ReactiveFormsModuleal shared.module.tstroppo:

(grazie a @Undrium per l' esempio di codice ):

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

Questo ha risolto il mio problema. Aggiungerlo solo ad app.module non era abbastanza
emirhosseini

3

Ho avuto questo problema e mi sono reso conto di non aver vincolato il mio componente a una variabile.

Cambiato

<input #myComponent="ngModel" />

per

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


2

Il modo corretto di utilizzare i moduli ora in Angular2 è:

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

Il vecchio modo non funziona più


1

Ho anche realizzato questo problema quando si cerca di combinare approcci di forma reattiva e forma modello. Ho avuto #name="ngModel"e [formControl]="name"sullo stesso elemento. La rimozione di uno dei due ha risolto il problema. Inoltre non è che se usi #name=ngModeldovresti avere anche una proprietà come questa [(ngModel)]="name", altrimenti otterrai comunque degli errori. Questo vale anche per gli angolari 6, 7 e 8.


0

Verifica di avere entrambi gli ngModel and nameattributi nella tua selezione. Anche Select è un componente del modulo e non l'intero modulo, quindi una dichiarazione più logica di riferimento locale sarà: -

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

Un'altra cosa importante è assicurarsi di importare FormsModulenel caso dell'approccio basato sui modelli o ReactiveFormsModulenel caso dell'approccio reattivo. Oppure puoi importare entrambi, il che va benissimo.


0

se ngModulenon funziona in input significa provare ... rimuovere le virgolette doppie intornongModule

piace

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

invece che sopra

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

-1

Ho avuto questo problema perché avevo un errore di battitura nel mio modello vicino a [(ngModel)]]. Staffa extra. Esempio:

<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">
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.