Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How [class] [attr] [style] directives work

I examined ngStyle, ngClass directives here but I still couldn't understand how these work:

<div [attr.role]="myAriaRole">
<div [class.extra-sparkle]="isDelightful">
<div [style.width.px]="mySize">

Built-in directives don't select such an attribute: class.extra-sparkle. What kind of selector can select such html attribute? Which built-in directive handles this?

As far as I know html attributes with dot (style.width.px) are not legal already. Apparently the string withing square brackets don't passed directly as attributes. But where it is done? Which directive catches these notations?

like image 870
omeralper Avatar asked Oct 08 '17 13:10

omeralper


People also ask

What are attribute directives in Angular?

Angular attribute directives are a number of built-in directives that we can add to our HTML elements that give them a dynamic behavior. In summary, an attribute directive changes the appearance or behavior of a DOM element.

What are different types of directives in Angular?

The three types of directives in Angular are attribute directives, structural directives, and components.

Can we use multiple directives in Angular?

You can not use two structural directives on the same element. You need to wrap your element in another one. It's advised to use ng-container since it wont be rendered in DOM.

What is style binding in Angular?

Style binding is used to set a style of a view element. We can set the inline styles of an HTML element using the style binding in angular. You can also add styles conditionally to an element, hence creating a dynamically styled element.


2 Answers

You're right, these are not directives.

Angular compiler creates a view factory for each component with view nodes. For each view node the compiler defines a set of bindings types using the bitmask. There are different binding types and hence different types of operations performed during change detection to reflect changes in the component class.

You probably know about the standard input mechanism that allows updating the property:

<div [prop]="myAriaRole">

The compiler creates the TypeProperty binding for it:

TypeProperty = 1 << 3

and hence the operation to update the element property is used during change detection.

The special syntax attr.*, class.* and style.* defines different type of bindings:

TypeElementAttribute = 1 << 0,
TypeElementClass = 1 << 1,
TypeElementStyle = 1 << 2,

so during change detection for each type of binding corresponding operation is used:

function CheckAndUpdateElement() {
    ...
    case BindingFlags.TypeElementAttribute -> setElementAttribute
    case BindingFlags.TypeElementClass     -> setElementClass
    case BindingFlags.TypeElementStyle     -> setElementStyle
    case BindingFlags.TypeProperty         -> setElementProperty;

To learn about Angular internals related to view and bindings I strongly recommend reading:

  • The mechanics of DOM updates in Angular
  • The mechanics of property bindings update in Angular
  • Here is why you will not find components inside Angular

Since all bindings are processed during change detection also read:

  • Everything you need to know about change detection in Angular
like image 191
Max Koretskyi Avatar answered Oct 31 '22 00:10

Max Koretskyi


The following code snippets are excerpted from the Angular.io docs.

What you're referring to is the Binding target.

<img [src]="heroImageUrl">

The first div is referencing Attribute binding.

<table>
    <tr><td [attr.colspan]="1 + 1">One-Two</td></tr>
</table>

The second div is referencing Class binding.

<!-- toggle the "special" class on/off with a property -->
<div [class.special]="isSpecial">The class binding is special</div>

<!-- binding to `class.special` trumps the class attribute -->
<div class="special"
     [class.special]="!isSpecial">This one is not so special</div>

However, it is recommended to use NgClass.

The last div is referencing Style binding. Believe it or not, the third div is actually legal (or at least in Angular).

<button [style.color]="isSpecial ? 'red': 'green'">Red</button>
<button [style.background-color]="canSave ? 'cyan': 'grey'" >Save</button>

However, it is recommended to use NgStyle instead.

So, in this case, it will bind the value of the variable to the element. (Except the class where it will evaluate whether the isDelightful variable is true.)

<div [attr.role]="myAriaRole"></div>
<div [class.extra-sparkle]="isDelightful"></div>
<div [style.width.px]="mySize"></div>

Here's a Stackblitz demo for you to play around with. :)

like image 39
Edric Avatar answered Oct 30 '22 23:10

Edric