Please, can you help me? It is supposed to be easy, but I can't find the solution. There is a form with two selects. When #select1 changes, #select2 needs to show data according to the value of #select1. For example, get cities of each state. Kind of :
//html
<select (change)="select2.getCities($event)" ng-control="userState">
<option *ng-for="#state of states" [value]="state">{{state}}</option>
</select>
<select #select2 ng-control="userCity">
<option *ng-for="#city of cities" [value]="city">{{city}}</option>
</select>
//the Component
@Component({ selector: 'user-management', appInjector: [FormBuilder] });
@View({ templateUrl: 'user-management.html', directives: [NgFor] });
export class userManagement {
constructor(fb: FormBuilder){
this.userForm = fb.group({
userState: [],
userCity: []
});
this.states = ['New York', 'Pennsylvania'];
this.cities = {'New York': ['Albany', 'Buffalo'], 'Pennsylvania':['Pittsburgh', 'Philadelphia']};
}
getCities($event){
return this.cities[$event.target.value];
}
}
This, of course, doesn't work. PLEASE, do you know how it should be done? It's in alpha28.
Please, can you help me? It is supposed to be easy, but I can't find the solution. There is a form with two selects. When #select1 changes, #select2 needs to show data according to the value of #select1. For example, get cities of each state. Kind of :
//html
<select (change)="select2.getCities($event)" ng-control="userState">
<option *ng-for="#state of states" [value]="state">{{state}}</option>
</select>
<select #select2 ng-control="userCity">
<option *ng-for="#city of cities" [value]="city">{{city}}</option>
</select>
//the Component
@Component({ selector: 'user-management', appInjector: [FormBuilder] });
@View({ templateUrl: 'user-management.html', directives: [NgFor] });
export class userManagement {
constructor(fb: FormBuilder){
this.userForm = fb.group({
userState: [],
userCity: []
});
this.states = ['New York', 'Pennsylvania'];
this.cities = {'New York': ['Albany', 'Buffalo'], 'Pennsylvania':['Pittsburgh', 'Philadelphia']};
}
getCities($event){
return this.cities[$event.target.value];
}
}
This, of course, doesn't work. PLEASE, do you know how it should be done? It's in alpha28.
Share Improve this question edited Jul 2, 2015 at 8:05 kakaja asked Jul 2, 2015 at 7:20 kakajakakaja 7342 gold badges10 silver badges22 bronze badges3 Answers
Reset to default 6Great! I found out how to make it work! :) The only thing that was missing, was the form model passed to the event. It should be like this:
<form [ng-form-model]="userForm">
<select (change)="select2.getCities($event, userForm)" ng-control="userState">
<option *ng-for="#state of states" [value]="state">{{state}}</option>
</select>
Answering with Angular 2 latest template syntax and Typescript component
//The Component Type script
import {Component} from 'angular2/core';
import {NgForm} from 'angular2/common';
@Component({ selector: 'states-cities',
template: `
<form (ngSubmit)="onSubmit()" #heroForm="ngForm">
<select ngControl="state" #state="ngForm" (change)="getCities(state)">
<option *ngFor="#state of states" [value]="state" >{{state}}</option>
</select>
<select ngControl="userCity" #select2="ngForm">
<option *ngFor="#city of cities" [value]="city">{{city}}</option>
</select>
</form>
`
})
export class stateCitiesComponent {
states= ['New York', 'Pennsylvania'];
cities = [];
citiesData={'New York': ['Albany', 'Buffalo'], 'Pennsylvania':['Pittsburgh', 'Philadelphia']};
getCities(state){
this.cities=this.citiesData[state.value];
}
}
This is how I would do it on Angular 2 RC5, with a model-driven approach and Observables. This could also be a search field where you then use debounceTime()
to not hit your backend on every keystroke or manipulate the input further.
//The Component Type script
import { Component } from '@angular/core';
import { FormControl, FormGroup, FormBuilder } from '@angular/forms';
@Component({
moduleId: module.id,
selector: 'states-cities',
template: `
<form [formGroup]="myForm" (ngSubmit)="onSubmit()">
<select formControlName="state">
<option *ngFor="let state of states" [value]="state" >{{state}}</option>
</select>
<select formControlName="userCity">
<option *ngFor="let city of cities" [value]="city">{{city}}</option>
</select>
</form>
`
})
export class stateCitiesComponent {
states:Array<string>;
cities:Array<string>;
citiesData:any;
myForm:FormGroup;
constructor(private formBuilder: FormBuilder) {
this.states = ['New York', 'Pennsylvania'];
this.cities = [];
this.citiesData = {'New York': ['Albany', 'Buffalo'], 'Pennsylvania':['Pittsburgh', 'Philadelphia']};
// Setup Form
this.myForm = this.formBuilder.group({
state: [''],
userCity: ['']
});
// Now setup change detection with an Observable
this.myForm.controls["state"].valueChanges
.debounceTime(100) // wait a litle after the user input (ms)
.subscribe(state => {
this.cities = this.citiesData[state];
});
}
onSubmit() {
// do something
}
}
You can read more about change detection here.