I am trying to extend the Angular template driven form given in the tutorial at angular.io/guide/forms. I have added a select
control whose values are based on the following model:
export class Power {
constructor(
public val: string,
public txt: string,
) { }
}
When the form is completed, the output is sent to both the console and the page. I can update the values of input
fields and they are immediately updated on the page (specifically, to div
) and in the console, but the select
element does not update. I have a feeling I'm not binding to the right elements, or perhaps my overall model is incorrect. The code is included below. I'd appreciate any input; TIA!
hero-form.component.ts:
import { Component } from '@angular/core';
import { Hero } from '../_models/hero';
import { Power } from '../_models/power'
@Component({
selector: 'app-hero-form',
templateUrl: './hero-form.component.html',
styleUrls: ['./hero-form.component.css']
})
export class HeroFormComponent {
powers = [
new Power('Strong', 'Really strong'),
new Power('Smart', 'Really smart'),
new Power('Hot','Really hot'),
new Power('Cold','Really cold'),
new Power('Weather','Weather changer'),
new Power('Time','Time traveller'),
];
model = new Hero('', this.powers[0], '');
submitted: boolean = false;
onSubmit: Function = () => {
console.log(this.model);
this.submitted = true;
}
constructor() { }
}
hero-form.component.html:
<h1>Hero Form</h1>
<form #HeroForm="ngForm" (ngSubmit)="onSubmit(HeroForm)">
<div >
<label for="Name">Name</label>
<input
type="text"
name="Name"
id="Name"
[(ngModel)]="model.name"
#name="ngModel"
required>
<p *ngIf="name?.touched && name?.errors"
>
Name is required!
</p>
</div>
<div >
<label for="Alias">Alias</label>
<input
type="text"
name="Alias"
id="Alias"
[(ngModel)]="model.alias"
required
#alias="ngModel">
<p *ngIf="alias?.touched && alias?.errors"
>
Alias is required!
</p>
</div>
<div >
<label for="power">Hero Power</label>
<select
id="power"
name="power"
required
[(ngModel)]="model.power"
#power="ngModel">
<option
*ngFor="let pow of powers;"
[ngValue]="pow.val">
{{pow.txt}}
</option>
</select>
</div>
<button type="submit" [disabled]="!HeroForm.valid">Submit</button>
</form>
<div *ngIf="model.name && model.alias">
<p >{{model.name}}</p>
<p >{{model.alias}}</p>
<p >
<span >***</span>
{{model.power.val}} <!-- THIS value does not update -->
<span >***</span>
</p>
</div>
<p>{{HeroForm.value | json}}</p>
CodePudding user response:
You need to assign the whole power object as the value of each select option. Otherwise it will just save the val
string in the model.power
property .
<option
*ngFor="let pow of powers;"
[ngValue]="pow"> // <------
{{pow.txt}}
</option>
Cheers