Daniel
Daniel

Reputation: 609

One way data binding in Angular2

I got the following html

<app-grid [columns]="columns" [data]="data" ></app-grid>

I want the data and columns properties to be immutable. The Grid should only show it. But in cases of sort or filtering the data would change, at least the order.

But here is my problem. If I access the data array and modify one property of an containing object. Like this.

this.data[0].name = "test"

The original gets changed. But I thought [data] is only one way data bound.

Could somebody point me in the right direction, to why this is happening and how I can omit it. I come from React where this would be pretty straight forward.

Upvotes: 17

Views: 36227

Answers (4)

Rajeev Jayaswal
Rajeev Jayaswal

Reputation: 1501

From Angular official documentation:

enter image description here

Upvotes: 12

fgul
fgul

Reputation: 6501

Firstly, you need to understand what databinding means in Angular?

What are Databindings ?

"Data bindings are expressions embedded into templates and are evaluated to produce dynamic content in the HTML document. Data bindings provide the link between the HTML elements in the HTML document and in template files with the data and code in the application."(from Pro Angular book)

[target]: expression

The square brackets indicate a one-way data binding where data flows from the expression to the target. One-way databindings in only one direction, which data flows from component to html template file.

{{expression}}

String interpolation binding, that is used to include expression results in the text content of host elements.

(target) ="expr"

The round brackets indicate a one-way binding where the data flows from the target to the destination specified by the expression. This is the binding used to handle events.

[(target)] ="expr"

This combination of brackets—known as the banana-in-a-box—indicates a two-way binding, where data flows in both directions between the target and the destination specified by the expression.

Upvotes: 1

Javan R.
Javan R.

Reputation: 2131

  • if you use [ngModel], [value], {{ param }} etc. you have one-way binding, model to view,
  • if you use (ngModelChange) you have one-way binding, view to model,
  • if you use [(ngModel)] you have two way binding.

But you are using a sub-component with the input @Input() property and this dances out of the line ;-) The notation is not what it looks like because it's always binded.

<sub-component [prop]="myObj"></sub-component>

So if you change the myObj in your sub-component, it will be binded:

ngOnInit() {
    this.myObj = this.myObj.push(this.newObj);
}

You could work with a local copy of myObj to prevent binding.

If you need an update from model you can push it with @Output() as Event:

<sub-component [prop]="myObj" (update)="myObj = $event"></sub-component>

Upvotes: 35

Marcin
Marcin

Reputation: 1426

You are right, syntax [target]=expression is a one way data binding, but I think that you have misunderstood the idea of the one way data binding.

One way data binding from data source to the view target means that values from the view are not passed back to the component, while any changes made to the expression in the component are reflected in the view - it is one way data binding from data source to the view, what does not mean that it is one time one way data binding.

On the other hand you may find one way data binding from the view target to data source with syntax (target)=expression which is used for passing events back to the components.

You can find more about Angular2 data binding in the docs here: https://angular.io/docs/ts/latest/guide/template-syntax.html#!#binding-syntax.

Upvotes: 16

Related Questions