Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

when use [name] vs [attr.name]?

Tags:

html

angular

Does anyone know why you can use [id] and you must use [attr.contenteditable] as property binding in Angular?

I have researched for some time and I can't find an answer.

Why some html native attributes can be modified just with its name while others need to be modified through the attr property?

like image 684
Guille Timon Avatar asked Mar 02 '23 18:03

Guille Timon


2 Answers

(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:
      • Use [propertyName]
    • 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.
like image 137
Dai Avatar answered Mar 05 '23 16:03

Dai


From the docs

Though the target name is usually the name of a property, there is an automatic attribute-to-property mapping in Angular for several common attributes. These include class/className, innerHtml/innerHTML, and tabindex/tabIndex.

So not all attributes are mapped within Angular.

Using the attr. prefix will literally emit the suffix as a string attribute.

Take this example:

<div [attr.data-my-attr]="value"></div>

Will produce the following HTML, assuming that the component property value has a value of 5:

<div data-my-attr="5">
</div>

Why you must use [attr.contenteditable]="editable"?

This isn't true. This is one way of emitting the contenteditable="true" attribute. Another is to use the Angular attribute [contentEditable]="editable", assuming some component property editable exists.

<div [contentEditable]="editable"></div>

DEMO: https://stackblitz.com/edit/angular-ujd5cf

like image 32
Kurt Hamilton Avatar answered Mar 05 '23 14:03

Kurt Hamilton