I have a select list that is bound to an Person property on my component using [ngValue]. When I change the select, the underyling selectedPerson property is updated as expected. However, the select does no default to the selected person on initialisation nor does it update if I change the selected person in code.
Any help into what I am missing would be greatly appreciated. Here's my code...
import {Component, OnInit, NgModule} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'
import { FormsModule } from '@angular/forms';
@Component({
selector: 'my-app',
template: `
<form>
<select [(ngModel)]="selectedPerson"
name="selectedPerson">
<option [ngValue]="null">Please choose...</option>
<option *ngFor="let p of people"
[ngValue]="p"
[attr.selected]="p.personId === selectedPerson?.personId ? true : null ">{{p.name}}</option>
</select>
<p>The selected person is {{selectedPerson?.name}}</p>
<button type="button" (click)="selectJane()">Select Jane</button>
<button type="button" (click)="clearSelection()">Clear Selection</button>
</form>`,
})
export class App implements OnInit {
public ngOnInit() {
this.people = [
{ personId: 1, name: "Tom" },
{ personId: 2, name: "Mary" },
{ personId: 3, name: "Jane" }
]
this.selectedPerson = { personId: 2, name: "Mary" }
}
public people: Person[];
public selectedPerson: Person;
public selectJane(){
this.selectedPerson = { personId: 3, name: "Jane" }
}
public clearSelection(){
this.selectedPerson = null;
}
}
export class Person {
public personId: number;
public name: string;
}
@NgModule({
imports: [ BrowserModule, FormsModule ],
declarations: [ App ],
bootstrap: [ App ]
})
export class AppModule {}
...and here's a Plunker http://plnkr.co/edit/ag94mZO9Zggg1kZx8jJV
You can see that the former is property binding where as the latter is event binding and the combination of both results in two-way binding in Angular. Syntax for two-way data binding in Angular is [ ()]. The [ ()] syntax combines the brackets of property binding, [], with the parentheses of event binding, ().
The [ ()] syntax combines the brackets of property binding, [], with the parentheses of event binding, (). This syntax for two-way binding is also known as banana in a box. [ ( )] = BANANA IN A BOX It is just a visual way to remember that the parentheses go inside the brackets. In Angular ngModel directive is used for two-way bindings.
So here the role of NgModel directive comes into the picture to work as bridge that enables two-way binding to HTML elements. It provides the required name pattern of target as ngModel in property binding and ngModelChange in event binding.
A default color initialized by component property will be selected initially in select box and a sample text is using that color. On change of color in select box, the color of text will change. Here we are using NgModel for two-way binding.
The problem is, that by using ngValue
, the select
expects the same reference, not just a similar looking object.
You could add a method to select by name like this:
public selectByName(name: string) {
this.selectedPerson = this.people.find(person => person.name === name);
}
And then call it in your ngOnInit()
:
this.selectByName("Mary");
// or this.selectedPerson = this.people[2];
And in selectJane()
:
public selectJane(){
this.selectByName("Jane");
}
Your updated Plunker
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With