2019-12-02 15:47:19 -05:00
# Attribute directives
2017-03-31 19:57:13 -04:00
2020-11-24 08:49:34 -05:00
With attribute directives, you can change the appearance or behavior of DOM elements and Angular components.
2017-02-22 13:09:39 -05:00
2020-11-24 08:49:34 -05:00
< div class = "alert is-helpful" >
2017-03-27 11:08:53 -04:00
2020-11-24 08:49:34 -05:00
See the < live-example > < / live-example > for a working example containing the code snippets in this guide.
2017-03-31 19:57:13 -04:00
2020-11-24 08:49:34 -05:00
< / div >
2019-02-06 03:17:13 -05:00
2020-11-24 08:49:34 -05:00
## Building an attribute directive
2019-02-06 03:17:13 -05:00
2020-11-24 08:49:34 -05:00
This section walks you through creating a highlight directive that sets the background color of the host element to yellow.
2017-03-11 08:44:25 -05:00
2020-11-24 08:49:34 -05:00
1. To create a directive, use the CLI command [`ng generate directive` ](cli/generate ).
2017-03-11 08:44:25 -05:00
2021-05-07 06:28:39 -04:00
< code-example language = "sh" >
2017-10-17 19:42:05 -04:00
ng generate directive highlight
< / code-example >
2017-03-11 08:44:25 -05:00
2020-11-24 08:49:34 -05:00
The CLI creates `src/app/highlight.directive.ts` , a corresponding test file `src/app/highlight.directive.spec.ts` , and declares the directive class in the `AppModule` .
2017-10-17 19:42:05 -04:00
2020-11-24 08:49:34 -05:00
The CLI generates the default `src/app/highlight.directive.ts` as follows:
2017-10-17 19:42:05 -04:00
2020-11-24 08:49:34 -05:00
< code-example path = "attribute-directives/src/app/highlight.directive.0.ts" header = "src/app/highlight.directive.ts" > < / code-example >
2017-03-31 19:57:13 -04:00
2020-11-24 08:49:34 -05:00
The `@Directive()` decorator's configuration property specifies the directive's CSS attribute selector, `[appHighlight]` .
2017-03-11 08:44:25 -05:00
2020-11-24 08:49:34 -05:00
1. Import `ElementRef` from `@angular/core` .
`ElementRef` grants direct access to the host DOM element through its `nativeElement` property.
2017-03-11 08:44:25 -05:00
2020-11-24 08:49:34 -05:00
1. Add `ElementRef` in the directive's `constructor()` to [inject ](guide/dependency-injection ) a reference to the host DOM element, the element to which you apply `appHighlight` .
2017-03-31 19:57:13 -04:00
2020-11-24 08:49:34 -05:00
1. Add logic to the `HighlightDirective` class that sets the background to yellow.
2017-10-17 19:42:05 -04:00
2020-11-24 08:49:34 -05:00
< code-example path = "attribute-directives/src/app/highlight.directive.1.ts" header = "src/app/highlight.directive.ts" > < / code-example >
2017-03-11 08:44:25 -05:00
2018-07-19 18:00:08 -04:00
< div class = "alert is-helpful" >
2017-03-27 11:08:53 -04:00
2020-11-24 08:49:34 -05:00
Directives _do not_ support namespaces.
2017-02-22 13:09:39 -05:00
2020-11-24 08:49:34 -05:00
< code-example path = "attribute-directives/src/app/app.component.avoid.html" header = "src/app/app.component.avoid.html (unsupported)" region = "unsupported" > < / code-example >
2017-03-27 11:08:53 -04:00
2017-04-10 11:51:13 -04:00
< / div >
2017-03-27 11:08:53 -04:00
2017-10-17 19:42:05 -04:00
{@a apply-directive}
2020-11-24 08:49:34 -05:00
## Applying an attribute directive
2017-02-22 13:09:39 -05:00
2020-11-24 08:49:34 -05:00
1. To use the `HighlightDirective` , add a `<p>` element to the HTML template with the directive as an attribute.
2017-02-22 13:09:39 -05:00
2020-11-24 08:49:34 -05:00
< code-example path = "attribute-directives/src/app/app.component.1.html" header = "src/app/app.component.html" region = "applied" > < / code-example >
2017-02-22 13:09:39 -05:00
2020-11-24 08:49:34 -05:00
Angular creates an instance of the `HighlightDirective` class and injects a reference to the `<p>` element into the directive's constructor, which sets the `<p>` element's background style to yellow.
2017-02-22 13:09:39 -05:00
2017-04-30 16:10:32 -04:00
{@a respond-to-user}
2017-03-31 19:57:13 -04:00
2020-11-24 08:49:34 -05:00
## Handling user events
2017-03-31 19:57:13 -04:00
2020-11-24 08:49:34 -05:00
This section shows you how to detect when a user mouses into or out of the element and to respond by setting or clearing the highlight color.
2017-02-22 13:09:39 -05:00
2020-11-24 08:49:34 -05:00
1. Import `HostListener` from '@angular/core'.
2017-02-22 13:09:39 -05:00
2020-11-24 08:49:34 -05:00
< code-example path = "attribute-directives/src/app/highlight.directive.2.ts" header = "src/app/highlight.directive.ts (imports)" region = "imports" > < / code-example >
2017-03-27 11:08:53 -04:00
2020-11-24 08:49:34 -05:00
1. Add two event handlers that respond when the mouse enters or leaves, each with the `@HostListener()` decorator.
2017-03-27 11:08:53 -04:00
2020-11-24 08:49:34 -05:00
< code-example path = "attribute-directives/src/app/highlight.directive.2.ts" header = "src/app/highlight.directive.ts (mouse-methods)" region = "mouse-methods" > < / code-example >
2017-10-17 19:42:05 -04:00
2020-11-24 08:49:34 -05:00
With the `@HostListener()` decorator, you can subscribe to events of the DOM element that hosts an attribute directive, the `<p>` in this case.
2017-03-27 11:08:53 -04:00
2020-11-24 08:49:34 -05:00
The handlers delegate to a helper method, `highlight()` , that sets the color on the host DOM element, `el` .
2017-03-31 19:57:13 -04:00
2020-11-24 08:49:34 -05:00
The complete directive is as follows:
2017-02-22 13:09:39 -05:00
2018-10-11 07:29:59 -04:00
< code-example path = "attribute-directives/src/app/highlight.directive.2.ts" header = "src/app/highlight.directive.ts" > < / code-example >
2017-03-31 19:57:13 -04:00
2020-11-24 08:49:34 -05:00
The background color appears when the pointer hovers over the paragraph element and disappears as the pointer moves out.
2017-03-11 08:44:25 -05:00
2019-11-11 17:47:51 -05:00
< div class = "lightbox" >
< img src = "generated/images/guide/attribute-directives/highlight-directive-anim.gif" alt = "Second Highlight" >
< / div >
2017-02-22 13:09:39 -05:00
2017-04-30 16:10:32 -04:00
{@a bindings}
2020-11-24 08:49:34 -05:00
## Passing values into an attribute directive
2017-03-31 19:57:13 -04:00
2020-11-24 08:49:34 -05:00
This section walks you through setting the highlight color while applying the `HighlightDirective` .
2017-02-22 13:09:39 -05:00
2020-11-24 08:49:34 -05:00
1. In `highlight.directive.ts` , import `Input` from `@angular/core` .
2017-03-27 11:08:53 -04:00
2020-11-24 08:49:34 -05:00
< code-example path = "attribute-directives/src/app/highlight.directive.3.ts" header = "src/app/highlight.directive.ts (imports)" region = "imports" > < / code-example >
2017-03-31 19:57:13 -04:00
2020-11-24 08:49:34 -05:00
1. Add an `appHighlight` `@Input()` property.
2017-03-27 11:08:53 -04:00
2021-03-10 04:43:00 -05:00
< code-example path = "attribute-directives/src/app/highlight.directive.3.ts" header = "src/app/highlight.directive.ts" region = "input" > < / code-example >
2017-03-31 19:57:13 -04:00
2020-11-24 08:49:34 -05:00
The `@Input()` decorator adds metadata to the class that makes the directive's `appHighlight` property available for binding.
2017-03-27 11:08:53 -04:00
2020-11-24 08:49:34 -05:00
1. In `app.component.ts` , add a `color` property to the `AppComponent` .
2017-03-31 19:57:13 -04:00
2020-11-24 08:49:34 -05:00
< code-example path = "attribute-directives/src/app/app.component.1.ts" header = "src/app/app.component.ts (class)" region = "class" > < / code-example >
2017-03-27 11:08:53 -04:00
2020-11-24 08:49:34 -05:00
1. To simultaneously apply the directive and the color, use property binding with the `appHighlight` directive selector, setting it equal to `color` .
2017-03-31 19:57:13 -04:00
2020-11-24 08:49:34 -05:00
< code-example path = "attribute-directives/src/app/app.component.html" header = "src/app/app.component.html (color)" region = "color" > < / code-example >
2017-02-22 13:09:39 -05:00
2020-11-24 08:49:34 -05:00
The `[appHighlight]` attribute binding performs two tasks:
2017-03-27 11:08:53 -04:00
2020-11-24 08:49:34 -05:00
* applies the highlighting directive to the `<p>` element
* sets the directive's highlight color with a property binding
2017-03-31 19:57:13 -04:00
2020-11-24 08:49:34 -05:00
### Setting the value with user input
2017-02-22 13:09:39 -05:00
2020-11-24 08:49:34 -05:00
This section guides you through adding radio buttons to bind your color choice to the `appHighlight` directive.
2017-03-31 19:57:13 -04:00
2020-11-24 08:49:34 -05:00
1. Add markup to `app.component.html` for choosing a color as follows:
2017-02-22 13:09:39 -05:00
2020-11-24 08:49:34 -05:00
< code-example path = "attribute-directives/src/app/app.component.html" header = "src/app/app.component.html (v2)" region = "v2" > < / code-example >
2017-02-22 13:09:39 -05:00
2020-11-24 08:49:34 -05:00
1. Revise the `AppComponent.color` so that it has no initial value.
2017-03-27 11:08:53 -04:00
2020-11-24 08:49:34 -05:00
< code-example path = "attribute-directives/src/app/app.component.ts" header = "src/app/app.component.ts (class)" region = "class" > < / code-example >
2017-03-31 19:57:13 -04:00
2020-11-24 08:49:34 -05:00
1. Serve your application to verify that the user can choose the color with the radio buttons.
2017-02-22 13:09:39 -05:00
2020-11-24 08:49:34 -05:00
< div class = "lightbox" >
< img src = "generated/images/guide/attribute-directives/highlight-directive-v2-anim.gif" alt = "Animated gif of the refactored highlight directive changing color according to the radio button the user selects" >
< / div >
2017-02-22 13:09:39 -05:00
2017-04-30 16:10:32 -04:00
{@a second-property}
2017-03-31 19:57:13 -04:00
2020-11-24 08:49:34 -05:00
## Binding to a second property
2017-03-11 08:44:25 -05:00
2020-11-24 08:49:34 -05:00
This section guides you through configuring your application so the developer can set the default color.
2017-02-22 13:09:39 -05:00
2020-11-24 08:49:34 -05:00
1. Add a second `Input()` property to `HighlightDirective` called `defaultColor` .
2017-02-22 13:09:39 -05:00
2020-11-24 08:49:34 -05:00
< code-example path = "attribute-directives/src/app/highlight.directive.ts" header = "src/app/highlight.directive.ts (defaultColor)" region = "defaultColor" > < / code-example >
2017-03-27 11:08:53 -04:00
2020-11-24 08:49:34 -05:00
1. Revise the directive's `onMouseEnter` so that it first tries to highlight with the `highlightColor` , then with the `defaultColor` , and falls back to `red` if both properties are `undefined` .
2017-03-31 19:57:13 -04:00
2020-11-24 08:49:34 -05:00
< code-example path = "attribute-directives/src/app/highlight.directive.ts" header = "src/app/highlight.directive.ts (mouse-enter)" region = "mouse-enter" > < / code-example >
2017-03-27 11:08:53 -04:00
2020-11-24 08:49:34 -05:00
1. To bind to the `AppComponent.color` and fall back to "violet" as the default color, add the following HTML.
In this case, the `defaultColor` binding doesn't use square brackets, `[]` , because it is static.
2017-03-31 19:57:13 -04:00
2020-11-24 08:49:34 -05:00
< code-example path = "attribute-directives/src/app/app.component.html" header = "src/app/app.component.html (defaultColor)" region = "defaultColor" > < / code-example >
2017-02-22 13:09:39 -05:00
2020-11-24 08:49:34 -05:00
As with components, you can add multiple directive property bindings to a host element.
2017-03-27 11:08:53 -04:00
2020-11-24 08:49:34 -05:00
The default color is red if there is no default color binding.
When the user chooses a color the selected color becomes the active highlight color.
2017-03-31 19:57:13 -04:00
2020-11-24 08:49:34 -05:00
< div class = "lightbox" >
< img src = "generated/images/guide/attribute-directives/highlight-directive-final-anim.gif" alt = "Animated gif of final highlight directive that shows red color with no binding and violet with the default color set. When user selects color, the selection takes precedence." >
< / div >
2017-02-22 13:09:39 -05:00
2020-11-24 08:49:34 -05:00
{@a ngNonBindable}
2017-03-11 08:44:25 -05:00
2020-11-24 08:49:34 -05:00
## Deactivating Angular processing with `NgNonBindable`
2017-02-22 13:09:39 -05:00
2020-11-24 08:49:34 -05:00
To prevent expression evaluation in the browser, add `ngNonBindable` to the host element.
`ngNonBindable` deactivates interpolation, directives, and binding in templates.
2020-06-14 04:53:19 -04:00
2020-11-24 08:49:34 -05:00
In the following example, the expression `{{ 1 + 1 }}` renders just as it does in your code editor, and does not display `2` .
2020-06-14 04:53:19 -04:00
< code-example path = "attribute-directives/src/app/app.component.html" linenums = "false" header = "src/app/app.component.html" region = "ngNonBindable" > < / code-example >
2020-11-24 08:49:34 -05:00
Applying `ngNonBindable` to an element stops binding for that element's child elements.
However, `ngNonBindable` still allows directives to work on the element where you apply `ngNonBindable` .
In the following example, the `appHighlight` directive is still active but Angular does not evaluate the expression `{{ 1 + 1 }}` .
2020-06-14 04:53:19 -04:00
< code-example path = "attribute-directives/src/app/app.component.html" linenums = "false" header = "src/app/app.component.html" region = "ngNonBindable-with-directive" > < / code-example >
2020-11-24 08:49:34 -05:00
If you apply `ngNonBindable` to a parent element, Angular disables interpolation and binding of any sort, such as property binding or event binding, for the element's children.