Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does @Input give a two way binding?

The way I thought @Input worked would directly give a big "No!" to this question. However, today I stumbled upon some strange behavior, or maybe I always thought the wrong way about @Input..

I've made a stackblitz to show the issue. This happens in the stackblitz for Angular 7.0.1, but in my local project, it also happens on Angular 6.1.2.

The stackblitz shows a simple parent component that has an object. The object is passed to a child component via @Input. Both the child and parent component have a function that changes the object. They also both show the object's value in the template.

I expected to see that when the parent changes the object, it will change it in the child. However, I did not expect that when the child changes the object, it also changes it for the parent. The stackblitz does show this behavior, however. I always thought you would need to explicitly emit an event via @Output to make a flow to the parent and change it there from the child component.

like image 553
Rink Stiekema Avatar asked Nov 08 '18 14:11

Rink Stiekema


People also ask

Which one is a example of two way data binding?

Two-way data binding refers to sharing data between a component class and its template. If you change data in one place, it will automatically reflate at the other end. For example, if you change the value of the input box, then it will also update the value of the attached property in a component class.

Which module is used to do two way binding?

Note: For two way data binding, we have to enable the ngModel directive. It depends upon FormsModule in angular/forms package, so we have to add FormsModule in imports[] array in the AppModule.

Is Angular 5'2 way binding?

The two-way data binding in Angular is used to display information to the end user and allows the end user to make changes to the underlying data using the UI. This makes a two-way connection between the view (the template) and the component class.

Is AngularJS supports two way binding?

AngularJS creates a two way data-binding between the select element and the $ctrl.


2 Answers

The answer is "no". In your example, the value that you pass to the @Input property is a reference to an object. If you had two-way binding, you could assign a new object to that property in the child component:

this.thing = { name: "world", nbm: 10 };

and the corresponding property in the parent component would be updated accordingly. That is not the case, as you can see in this stackblitz.

However, since the parent and child components have a reference to the same object, they can both modify one of its properties, and that change will be observed in the other component.


In order to implement two-way binding, you can add an @Output property with the same name followed by Change, and emit the event when the change occurs:

@Input() thing: any;
@Output() thingChange = new EventEmitter();

setNewObject(){
  this.thing = { name: "world", nmb: 10 };
  this.thingChange.emit(this.thing);
}

The change will then be reflected to the parent component if the two-way binding syntax is used:

<child2 [(thing)]="thing"></child2>

See this stackblitz for a demo.


If you want to prevent the child component from modifying the original object, you should bind the object properties instead of the object itself:

@Input() thingName: string;
@Input() thingNmb: number;
<child [thingName]="thing.name" [thingNmb]="thing.nmb"></child>
like image 174
ConnorsFan Avatar answered Oct 22 '22 14:10

ConnorsFan


Yes, Angular Change Detection flows from parent to child however what you are experiencing is not related to Object reference. Since the shared object in parent and child point to the same reference, it will update in both the component.

Whenever you make any change through child component, shared object will be changed in the parent component as well and Angular will detect changes and trigger the UI update.

However that is not same case with primitive data type. What you have thought is true for primitive data type. In case primitive data type changes moves from Parent to child not vice versa.

Here is the demo for the same - https://stackblitz.com/edit/angular-1wusrc

like image 45
Sunil Singh Avatar answered Oct 22 '22 15:10

Sunil Singh