Property binding vs attribute interpolation

Maryam Gharibi picture Maryam Gharibi · Aug 24, 2016 · Viewed 31.9k times · Source

I have read an article about difference between property and attribute bindings. From what I understood, most of the time, Angular2 prefers property bindings, because after each change in data, the DOM would be updated. (If I am mistaken, please correct me).

I have a custom component and use it from the parent component. In it, I have an @Input named truevalue. when I initiate truevalue from the parent via property binding, sometimes, it does not change. I used following code:

<my-checkbox [(ngModel)]="chkItems" [disabled]="!editMode" [trueValue]="Y"></my-checkbox>

If I send true or "1" into trueValue it works, but If I send "Y" or "YES", it does not work. So I am forced to use attribute binding. I don't know what is the problem.

I have changed it, into the following:

<my-checkbox [(ngModel)]="chkItems" [disabled]="!editMode" trueValue="Y"></my-checkbox>

Thanks in advance

Answer

G&#252;nter Z&#246;chbauer picture Günter Zöchbauer · Aug 24, 2016

Property binding like

[trueValue]="..."

evaluates the expression "..." and assigns the value

"true" evaluates to the value true "Y" is unknown. There is no internal Y value in TypeScript and no property in the component class instance, which is the scope of template binding. In this case you would want

[trueValue]="'Y'"

Note the additional quotes to make Y a string.

Plain attributes are also assigned to inputs

trueValue="Y"

is plain HTML without any Angular2 binding and attribute values are always strings. Therefore this would assign the string Y.

Another way is string interpolation

trueValue="{{true}}"

would assign the value "true" (as string) because the expression withing {{...}} would be evaluated and then converted to a string before passed to the input. This can't be used to bind other values than strings.

To explicitly bind to an attribute instead of a property you can use (besides trueValue="Y" which creates an attribute but doesn't do any evaluation)

[attr.trueValue]="'Y'"

or

attr.trueValue="{{'Y'}}"

Attribute binding is helpful if you want to use the trueValue attribute to address the element with CSS selectors.