Reputation: 17671
I've been looking at this code for a bit now and I'm stuck: I have a form that I'm binding to a component model and the [(ngModel)]
binding breaks the page - the page won't render. I get no compilation error and no runtime debugger error, but the page won't render.
On this page it appears the model is working fine - I can see the model value fine with {{todo.title}}
but when I try to bind the value to a form control with [(ngModel)]="todo.title" the application breaks.
Here's the form:
<form name="form1" id="form1" novalidate>
<div class="form-group">
<div class="input-group">
<span class="input-group-addon"><i class="fa fa-bookmark"></i> </span>
<input class="form-control"
name="title"
[(ngModel)]="todo.title"
placeholder="Enter the title for this ToDo"
required >
</div>
</div>
</form>
and the super simple components:
import { Component } from '@angular/core';
import { ToDo } from './todo';
import { ToDoListComponent } from './todo-list';
@Component({
selector: 'todo-entry',
templateUrl: 'app/todo-entry.html'
})
export class ToDoEntryComponent {
todo:ToDo = new ToDo();
new() {
this.todo = new ToDo();
}
}
and:
import { Component } from '@angular/core';
@Component({})
export class ToDo {
title:string = "new todo";
entered:Date = new Date();
}
The code works (one way anyway) if I use:
value="{{todo.title}}"
I'm pretty sure the module loading and component references are all correct as everything else works as expected displaying model values, as long as I don't use [(ngModel)].
Any ideas what I'm missing here?
Upvotes: 3
Views: 2181
Reputation: 4189
App module should look something like this. Make sure you import FormsModule
.
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
FormsModule,
HttpModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Upvotes: 1
Reputation: 1978
Your app.module.ts should look like this:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule, provideForms, disableDeprecatedForms } from '@angular/forms';
import { AppComponent } from './app.component';
@NgModule({
imports: [ BrowserModule, FormsModule ],
declarations: [ AppComponent ],
bootstrap: [ AppComponent ],
providers: [
disableDeprecatedForms(),
provideForms()],
})
export class AppModule { }
Upvotes: 0
Reputation: 17671
Never fails - posted this and found the answer here after some additional searching: http://almerosteyn.com/2016/04/linkup-custom-control-to-ngcontrol-ngmodel
The problem was missing imports for the Forms module. In RC5 and later the following has to be added to the module definition:
import { FormsModule } from '@angular/platform-browser';
and to the imports
declaration in @NgModule
:
@NgModule({
imports: [ BrowserModule,FormsModule ],
...
}
It's a pain that this error triggered no error during compilation as most other missing modules seem to do. Not sure why this one is not complaining...
Additionally, I had to make sure that I used name=title
in addition (or instead of) id=title
. name
attribute is required for bound form elements.
Upvotes: 2
Reputation: 1397
I think the problem is that angular sees your [(ngModel)]
and thinks you're trying to use an angular form, but there are no other supporting directives. I have no idea why you're not getting a helpful error description though.
If I create a simple form that uses ngModel
binding but does not otherwise use angular forms, I get this error:
Error: If ngModel is used within a form tag, either the name attribute must be set or the form control must be defined as 'standalone' in ngModelOptions.
Example 1: <input [(ngModel)]="person.firstName" name="first"> Example 2: <input [(ngModel)]="person.firstName" [ngModelOptions]="{standalone: true}">
So you can do what the error says and add [ngModelOptions]="{standalone: true}"
to your control, or you can use the blanket ngNoForm
on your form
element:
<form name="form1" id="form1" novalidate noNoform>
Upvotes: 3