简体   繁体   中英

Listen for changes on object update Angular

I have a form that updates an object directly like so

component.html

<input type="text" [(ngModel)]="user.name" />
<input type="text" [(ngModel)]="user.surname" />
<input type="text" [(ngModel)]="user.age" />

component.ts

user = {
  name: null,
  surname: null,
  age: null
}

now in my component.html I have a save button that is in a child component

<app-save-btn [user]="user"></app-save-btn>

and in the app-save-btn component I am listening for changes using OnChanges

@Input() user: User;

userForCompare: User;

ngOnChanges() {
  if (!this.userForCompare) {
    this.userForCompare = {...this.user};
  }
  console.log(this.userForCompare, this.user);
}

now my issue is, I get the first console log of the two user objects, but as I update further fields I no longer get change updates..

now I know that I could create seperate variables to hold each value, but I have like 30 field items so I dont want to change my implementation to much...

any help would be appreciated

@Input property will trigger ngOnChanges function only when the Input object is mutated.

In your example, input fields are mutating each single property in the same user object, the user object for the @Input always refers to the same object (even though its child property name, surename and age are mutated), so ngOnChanges will not be triggered.

Therefore, you have to make this.user in component.ts equals to a brand new user object whenever any input field is changed.

Hope it helps!

I would suggest creating a FormGroup with Reactive Forms to manipulate your fields. Using FormBuilder.group() you can create a form containing each for the property of the User object... that way you would only need to pass form.value to your child component.

Reactive form keeps the data model pure by providing it as an immutable data structure. Each time a change occurs to the form, the FormControl instance will not update the existing data model, it will return a new state (a new data model).
https://www.ibrahima-ndaw.com/blog/5-reasons-to-use-reactive-form/

Here is a live StackBlitz example using the code below:
https://stackblitz.com/edit/angular-stackoverflow-60424523

example.component.html

<form [formGroup]="form">
  <input [formControlName]="'name'" />
  <input [formControlName]="'surname'" />
  <input [formControlName]="'age'" />
</form>
<app-save-btn [user]="form.value"></app-save-btn>

example.component.ts

import { Component, OnInit} from '@angular/core';
import { FormBuilder, FormGroup} from '@angular/forms';

@Component({ ... })
export class AppComponent implements OnInit {

  form: FormGroup;

  user: User = {
    name: 'Initial name',
    surname: 'Initial surname',
    age: 99
  };

  constructor(
    private formBuilder: FormBuilder,
  ) { }

  ngOnInit() {
    this.form = this.formBuilder.group(this.user);
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM