Home > Net >  How to trigger ngOnChanges
How to trigger ngOnChanges

Time:06-09

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&nbsp;</label>
    <select name="extra1" >
      <option value="default">Kein Extra</option>
      <option *ngFor="let extra of selectExtra" [value]="extra.name">{{extra.name}} {{extra.preis}}&euro;</option>
    </select>
  </div>
  <div >
    <label for="gesamtpreis">Gesamt&nbsp;</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);
    });
}
  • Related