Property binding vs attribute interpolation
Solution 1
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.
Solution 2
I came to understand from the following sentences
First I will explain a little bit about html attribute and dom property
- Attributes are defined by html whereas properties are defined by DOM
- Attributes initialise DOM properties. Once initialisation complete attribute job is done
- Properties value can change whereas attribute value cannot change
For example
<input id="idInput" type="text" value="xyz" />
In console of a browser if we type
idInput.getAttribute('value') //attribute value gives xyz
idInput.value // property value also gives xyz
If we change the input text in textbox to tyz
:
idInput.getAttribute('value') // attribute value gives xyz
idInput.value // property value also gives tyz
Now different types of binding in angular
String Interpolation {{name}}
- Interpolation is a special syntax that Angular convert into a property binding
- To concatenate strings we must use interpolation instead of property binding
- To set an element property to a nonstring data value, you must property binding
Property Binding [disabled]="name"
Here [disabled]
is a property of DOM. Not the attribute disabled
found in html.
Attribute Binding attr.colspan ="{{colspanval}}"
When property corresponding to the attribute doesn't exist for example colspan doesn't have corresponding dom property so attribute binding is required.
Error is thrown in console if we try to use colspan = "{{cospanval}}"
- property binding
Solution 3
When rendering data values as strings, there is no technical reason to prefer one form to the other.
If we want data values as boolean or other than string then we should go for property binding
Solution 4
A couple of others have mentioned this, but I think a good example is important to highlight the difference. Suppose you have some radio buttons that are bound like this:
<div *ngFor="let item of results">
<input type="radio" value="{{item.id}}" name="{{item.id}}" [(ngModel)]="selectedItemId">
</div>
This would appear to work correctly, but if item.id
is a numeric value rather than a string, selectedItemId
would get set to a string value instead of an integer. This could cause defects in unexpected places. For example, using item.id == selectedItemId
might return true when item.id === selectedItemId
would always be false.
So I'd suggest that it's probably a good practice to always use property binding on the value
property, because it's specifically used to store and bind to values rather than just changing the HTML.
<div *ngFor="let item of results">
<input type="radio" [value]="item.id" name="{{item.id}}" [(ngModel)]="selectedItemId">
</div>
Same goes for boolean attributes. Note that in some cases like checked
and disabled
, Angular appears to treat interpolated values as booleans, but in others like hidden
, it doesn't. See this stackblitz for an example.
Solution 5
Property binding([]) and interpolation({{}}) , both are similar and both supports one way data binding(supply data from component to html template).There is a minor difference between them. We must use property binding for non-string data.such as
<div [disabled]='isdissabled'>Text</div>
here is property that is defined inside component.
isdissabled : boolean=true;(after that change it to false in both scenario it would work as expected)
<div disabled='{{isdissabled}}'>Text</div>
but this scenario would not work as expected(both scenario it would be dissabled).
Maryam Gharibi
Updated on July 09, 2022Comments
-
Maryam Gharibi almost 2 years
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
namedtruevalue
. when I initiatetruevalue
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"
intotrueValue
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
-
StriplingWarrior about 5 yearsI don't think divs are allowed to be disabled. Can you update this with an example that reproduces the problem you're describing?
-
Marek over 3 yearsBut which one of the last two examples provided by you should be preferred?
-
Günter Zöchbauer over 3 yearsThere is no general suggestion as far as I am aware of. Use what you prefer. I personally prefer
[]
because I hardly ever use{{}}
on attributes, only in element content, so I think it helps with distinguishing attributes from contents visually.