简体   繁体   中英

Why angular2 one-way binding between components works wrong with objects?

I have parent and child components.
I want to send form's values from parent to child component.
Child component can do everything with this data, but all changes are local and should not be returned back to parent component.

to child comp – everything works fine and changes doesn't returned back to parent.子组件- 一切正常,更改不会返回给父组件。
– all changes returns back to parent component...- 所有更改都返回到父组件......

Live

https://stackblitz.com/edit/angular-dvqyjr

Parent Component JS

export class AppComponent  {
constructor (private formBuilder: FormBuilder){};

simpleVariable = 'Value';
form: FormGroup = this.formBuilder.group({
    id: 1,
    name: 'Name'
});

Parent Component HTML

<hello [simpleVariable]="simpleVariable" [form]="form.value"></hello>

Child Component JS

export class HelloComponent  {
  @Input() simpleVariable;
  @Input() form;
}

Child Component HTML

<input [(ngModel)]="simpleVariable">
<input [(ngModel)]="form.name">

Question

So how can i send an object to child component and modify it without returning data to parent?

This is quite simple. The reason for this behavior is that the form.value is an object. Meaning that you're sharing a reference object with parent and child. Meaning that any change to this object will result in a change in both parent and child.

In order to make changes in child that won't affect your parent, create a deep copy of your object using Object.assign function and use it in your child component.

export class HelloComponent implements OnInit {
  _from: {};
  @Input() simpleVariable;
  @Input() form;

  ngOnInit() {
    this._form = {};
    Object.assign(this._from, this.form);
  }
}

Forked and edited example

From the Angular documentation at Reactive Forms - Step 2: Associating the FormGroup model and view :

A form group tracks the status and changes for each of its controls, so if one of the controls changes, the parent control also emits a new status or value change.

You can try the following one with the form:

<form [formGroup]="form">
  <input formControlName="name">
</form>

It all comes to Explaining Value vs. Reference in Javascript as well as Angular's Change Detection

Overall, @benshabatnoam already answered you'r question - in order to execute change detection - you need to change object reference, either by old fashioned way:

Object.assign(this._from, this.form);

Or ES6 way:

this._from = {...this.form}

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