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.