I have started a Visual Studio Community 2017 project using the Angular Single Page Application (SPA) template, as described in the .NET Web Development and Tools Blog:
2-way data binding using [(ngModel)] is not working.
For example: In login.component.html:
<input [(ngModel)]="x" name="x"/>
<h1>{{x}}</h1>
In login.component.ts:
export class LoginComponent {
x = 5;
}
Result:
When I change the value in the input box, the text in the h1 tag should change as well. But it doesn't change.
I have already tried importing the FormsModule from @angular/forms and adding FormsModule to the imports for the @NgModule decorator in app.module.ts as noted here: Angular 2 two way binding using ngModel is not working.
More info (added 2017-06-12): Note that the app module is divided up into three separate files
app.module.shared.ts:
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { AppComponent } from './components/app/app.component'
import { NavMenuComponent } from './components/navmenu/navmenu.component';
import { HomeComponent } from './components/home/home.component';
import { FetchDataComponent } from
'./components/fetchdata/fetchdata.component';
import { CounterComponent } from './components/counter/counter.component';
import { LoginComponent } from './components/login/login.component';
//dcowan: for login page
import { TimeEntryComponent } from
'./components/timeentry/timeentry.component'; //dcowan: for time entry page
export const sharedConfig: NgModule = {
bootstrap: [ AppComponent ],
declarations: [
AppComponent,
NavMenuComponent,
CounterComponent,
FetchDataComponent,
HomeComponent,
LoginComponent, //dcowan: for login page
TimeEntryComponent //dcowan: for time entry page
],
imports: [
RouterModule.forRoot([
{ path: '', redirectTo: 'home', pathMatch: 'full' },
{ path: 'home', component: HomeComponent },
{ path: 'login', component: LoginComponent }, //dcowan: for login page
{ path: 'timeentry', component: TimeEntryComponent }, //dcowan: for time entry page
{ path: 'counter', component: CounterComponent },
{ path: 'fetch-data', component: FetchDataComponent },
{ path: '**', redirectTo: 'home' }
])
]
};
app.module.client.ts:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
//import { FormsModule } from '@angular/forms';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import { sharedConfig } from './app.module.shared';
// dcowan: Imports for loading & configuring the in-memory web api
//import { InMemoryWebApiModule } from 'angular-in-memory-web-api';
//import { InMemoryDataService } from './in-memory-data.service';
import { DemoDbService } from './demo-db.service';
@NgModule({
bootstrap: sharedConfig.bootstrap,
declarations: sharedConfig.declarations,
imports: [
BrowserModule,
//FormsModule,
FormsModule,
HttpModule,
...sharedConfig.imports
],
providers: [DemoDbService,//dcowan: Dovico Web API
{ provide: 'ORIGIN_URL', useValue: location.origin }
]
})
export class AppModule {
}
app.module.server.ts:
import { NgModule } from '@angular/core';
import { ServerModule } from '@angular/platform-server';
import { sharedConfig } from './app.module.shared';
import { FormsModule } from '@angular/forms';
@NgModule({
bootstrap: sharedConfig.bootstrap,
declarations: sharedConfig.declarations,
imports: [
FormsModule,
ServerModule,
...sharedConfig.imports
]
})
export class AppModule {
}