(This answer assumes you're binding to a HTMLElement
rather than an in-app model object. Given the [attr.{name}]
-syntax is only supported for DOM HTMLElement
objects this assumption should stand)
When working with the DOM, the DOM interfaces for certain elements define first-class/native properties (as in JavaScript properties) for certain HTML attributes.
For example, the HTMLElement
DOM interface defines a first-class property id
, which is why you can directly use it in a binding expression: [id]
. Similarly the HTMLAnchorElement
exposes the href
property.
(I note that contenteditable
is a a defined DOM interface property in WHATWG HTML LS, but not the W3C's DOM specs, interesting...)
However, arbitrary (ultra-modern, user-defined, and obsolete) HTML attributes are not exposed through DOM interfaces and so can can only be accessed via the attributes
collection in the DOM. Angular requires you to use [attr.{name}]
for non-DOM-property attributes so that it knows it has to use the attributes
collection instead of assuming it can bind directly to a DOM property.
To answer your question more directly:
when use [name] vs [attr.name]?
Follow this flow-chart:
- Is the value I'm after exposed as a DOM interface property?
- Yes:
- No:
- Is the value I'm after a HTML attribute without a corresponding DOM interface property?
- Yes: Use
[attr.{attributeName}]
- No: Quit your job and let someone else deal with the emotional and mental stresses of the fast-moving JavaScript developer ecosystem.