How to trigger ngOnChanges on a form in a component?
I want to calculate a new total price (gesamtpreis) whenever any form input changes.
I looked at other answers, but this just made my code more weird instead of working. Do I need the @Input and is it correctly wired.
component HTML:
<div >
<div >
<form #carConfigurationForm="ngForm" ng-change="ngOnChanges">
<div >
<label for="extra">Extra 1 </label>
<select name="extra1" >
<option value="default">Kein Extra</option>
<option *ngFor="let extra of selectExtra" [value]="extra.name">{{extra.name}} {{extra.preis}}€</option>
</select>
</div>
<div >
<label for="gesamtpreis">Gesamt </label>
<span name="gesamtpreis" [innerHTML]="gesamtpreis"></span>
</div>
</form>
component code:
import { Component, OnInit, OnChanges, Input } from '@angular/core';
import { Extra } from '../model/extra';
import { ExtraService} from '../service/extra.service';
import { SimpleChanges } from '@angular/core';
@Component({
selector: 'app-car-configuration-form',
templateUrl: './car-configuration-form.component.html',
styleUrls: ['./car-configuration-form.component.sass']
})
export class CarConfigurationFormComponent implements OnInit, OnChanges {
selectExtra : Extra[] = [];
gesamtpreis : string = 'kein Preis';
constructor(private extraService: ExtraService) { }
getSelectedExtra(): void{
this.extraService.findAll()
.subscribe(selectExtra => this.selectExtra= selectExtra);
}
ngOnInit() {
this.getSelectedExtra();
}
@Input() extra1: string = '';
ngOnChanges(changes: SimpleChanges) {
// changes.prop contains the old and the new value...
console.log('zzz ngOnChanges');
this.gesamtpreis = "zzz"; //changes.toString();
}
}
CodePudding user response:
ngOnChanges
is not triggered because it is meant for component that recieves @Input
. It is a life cycle hook that gets triggered when @input
binded to some component is changed or reset.
Even if your component had some input
binded, you wouldn't be able to detect changes on form, because form is a native dom element for your component, you don't receive it via input.
ngOnChanges
performs change check only on the data that is recieved via input
You can subscribe to Form.valueChanges
for this.
CodePudding user response:
ngModel
Why do you want to use ngOnChanges exactly?
You can just use ngModel
to bind to values in a template form:
<select name="extra1" [ngModel]="gesamtpreis">
If you want other logic to trigger when the value changes you can just make getters and setters for that value:
private _gesamtpreis = 'kein Preis';
get gesamtpreis() {
return this._gesamtpreis
}
set gesamtpreis(value) {
this._gesamtpreis = value
/* Some other logic goes here... */
/* You could event push to a subject here, whatever floats your boat... */
}
Binding to the (change) event
<form #carConfigurationForm="ngForm" (change)="formChanged(carConfigurationForm)">
Script:
formChanged(event) {
console.log(event.value)
}
In your case you don't even need to pass the form reference into the function. Since it seems you only want to get some notice of the form being changed.
Here's a Stackblitz for you to play with.
CodePudding user response:
Forms possess a property valueChanges
to which you can subscribe.
you could do
// declare the variable referencing the ngForm
@ViewChild('carConfigurationForm') carConfigurationForm: NgForm;
selectedExtra: Extra[] = [];
and then
ngOnInit() {
this.getSelectedExtra();
this.carConfigurationForm.form.valueChanges.subscribe((newValue: any) => {
console.log('old value:', carConfigurationForm.form.value);
console.log('new value:', newValue);
});
}