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

≯℡__Kan透↙ 提交于 2019-12-04 08:16:55

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:

Since all bindings are processed during change detection also read:

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. :)

As @Edric specified here, the matter is the binding target. I firstly thought all of these are handled by a built-in directive

[attr.role]
[class.extra-sparkle]
[style.width.px]

like ngClass and ngStyle but it is not. None of these are directives, they are just synonyms of this:

bind-attr.role
bind-class.extra-sparkle
bind-style.width.px

and the bind prefix are compiled at template parser here. The "bind thing" is not a directive, it is build-in feature that compiler already handles all the bound properties, attributes etc.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!