i'm on the RC4 and i'm getting the error There is no directive with "exportAs" set to "ngForm" because of my template :
<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>
the 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]);
/// so here is my DropdownList :
<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>
//my component ts :
i was representing it in the old forms like this :
categoryControlGroups:ControlGroup[] = [];
categories:ControlArray = new ControlArray(this.categoryControlGroups);
and now i'm doing this :
categoryControlGroups:FormGroup[] = [];
categories:FormArray = new FormArray(this.categoryControlGroups);
you think it's the cause of the prob ??
Since 2.0.0.rc6:
forms: deprecated provideForms()
and disableDeprecatedForms()
functions have been removed. Please import the FormsModule
or the ReactiveFormsModule
from @angular/forms
instead.
In short:
- If you use template-driven forms, add
FormsModule
to your @NgModule
.
- If you use model-driven forms, add
ReactiveFormsModule
to your @NgModule
.
So, add to your app.module.ts
or equivalent:
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 { }
Failing to have one of these modules can lead to errors, including the one you face:
Can't bind to 'ngModel' since it isn't a known property of 'input'.
Can't bind to 'formGroup' since it isn't a known property of 'form'
There is no directive with "exportAs" set to "ngForm"
If you're in doubt, you can provide both the FormsModule
and the ReactiveFormsModule
together, but they are fully-functional separately. When you provide one of these modules, the default forms directives and providers from that module will be available to you app-wide.
Old Forms using ngControl
?
If you do have those modules at your @NgModule
, perhaps you are using old directives, such as ngControl
, which is a problem, because there's no ngControl
in the new forms. It was replaced more or less* by ngModel
.
For instance, the equivalent to <input ngControl="actionType">
is <input ngModel name="actionType">
, so change that in your template.
Similarly, the export in controls is not ngForm
anymore, it is now ngModel
. So, in your case, replace #actionType="ngForm"
with #actionType="ngModel"
.
So the resulting template should be (===>
s where changed):
<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>
* More or less because not all functionality of ngControl
was moved to ngModel
. Some just were removed or are different now. An example is the name
attribute, the very case you are having right now.
I faced the same issue. I had missed the forms module import tag in the app.module.ts
import { FormsModule } from '@angular/forms';
@NgModule({
imports: [BrowserModule,
FormsModule
],
I had the same problem which was resolved by adding the FormsModule to the .spec.ts:
import { FormsModule } from '@angular/forms';
and then adding the import to beforeEach:
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [ FormsModule ],
declarations: [ YourComponent ]
})
.compileComponents();
}));
In my case I had to add FormsModule
and ReactiveFormsModule
to the shared.module.ts
too:
(thanks to @Undrium for the code example):
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 { }
The correct way of use forms now in Angular2 is:
<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>
The old way doesn't works anymore
I had this problem because I had a typo in my template near [(ngModel)]]. Extra bracket. Example:
<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">
I had this problem and I realized I had not bound my component to a variable.
Changed
<input #myComponent="ngModel" />
to
<input #myComponent="ngModel" [(ngModel)]="myvar" />