Cambia la apariencia o comportamiento de elementos DOM y componentes Angular con directivas de atributo.
Construyendo una directiva de atributo
Esta sección te guía a través de la creación de una directiva de resaltado que establece el color de fondo del elemento host en amarillo.
Para crear una directiva, usa el comando CLI
ng generate directive.ng generate directive highlightEl CLI crea
src/app/highlight.directive.ts, un archivo de prueba correspondientesrc/app/highlight.directive.spec.ts.src/app/highlight.directive.ts
import {Directive} from '@angular/core';@Directive({ selector: '[appHighlight]',})export class HighlightDirective {}La propiedad de configuración del decorador
@Directive()especifica el selector de atributo CSS de la directiva,[appHighlight].Importa
ElementRefdesde@angular/core.ElementRefotorga acceso directo al elemento DOM host a través de su propiedadnativeElement.Añade
ElementRefen elconstructor()de la directiva para inyectar una referencia al elemento DOM host, el elemento al que aplicasappHighlight.Añade lógica a la clase
HighlightDirectiveque establece el fondo a amarillo.src/app/highlight.directive.ts
import {Directive, ElementRef, inject} from '@angular/core';@Directive({ selector: '[appHighlight]',})export class HighlightDirective { private el = inject(ElementRef); constructor() { this.el.nativeElement.style.backgroundColor = 'yellow'; }}
ÚTIL: Las directivas no soportan espacios de nombres.
src/app/app.component.avoid.html (no soportado)
<p app:Highlight>This is invalid</p>
Aplicando una directiva de atributo
- Para usar
HighlightDirective, añade un elemento<p>a la plantilla HTML con la directiva como atributo.src/app/app.component.html
<h1>My First Attribute Directive</h1><p appHighlight>Highlight me!</p><p appHighlight="yellow">Highlighted in yellow</p><p [appHighlight]="'orange'">Highlighted in orange</p><p [appHighlight]="color">Highlighted with parent component's color</p>
Angular crea una instancia de la clase HighlightDirective e inyecta una referencia al elemento <p> en el constructor de la directiva, que establece el estilo de fondo del elemento <p> a amarillo.
Manejando eventos de usuario
Esta sección te muestra cómo detectar cuando un usuario pasa el mouse sobre o fuera del elemento y responder estableciendo o limpiando el color de resaltado.
Importa
HostListenerdesde '@angular/core'.src/app/highlight.directive.ts (importaciones)
import {Directive, ElementRef, HostListener, inject} from '@angular/core';@Directive({ selector: '[appHighlight]',})export class HighlightDirective { private el = inject(ElementRef); @HostListener('mouseenter') onMouseEnter() { this.highlight('yellow'); } @HostListener('mouseleave') onMouseLeave() { this.highlight(''); } private highlight(color: string) { this.el.nativeElement.style.backgroundColor = color; }}Añade dos manejadores de eventos que responden cuando el mouse entra o sale, cada uno con el decorador
@HostListener().src/app/highlight.directive.ts (métodos-mouse)
import {Directive, ElementRef, HostListener, inject} from '@angular/core';@Directive({ selector: '[appHighlight]',})export class HighlightDirective { private el = inject(ElementRef); @HostListener('mouseenter') onMouseEnter() { this.highlight('yellow'); } @HostListener('mouseleave') onMouseLeave() { this.highlight(''); } private highlight(color: string) { this.el.nativeElement.style.backgroundColor = color; }}
Suscríbete a eventos del elemento DOM que aloja una directiva de atributo, el <p> en este caso, con el decorador @HostListener().
ÚTIL: Los manejadores delegan a un método auxiliar, highlight(), que establece el color en el elemento DOM host, el.
La directiva completa es la siguiente:
src/app/highlight.directive.ts
import {Directive, ElementRef, HostListener, inject} from '@angular/core';@Directive({ selector: '[appHighlight]',})export class HighlightDirective { private el = inject(ElementRef); @HostListener('mouseenter') onMouseEnter() { this.highlight('yellow'); } @HostListener('mouseleave') onMouseLeave() { this.highlight(''); } private highlight(color: string) { this.el.nativeElement.style.backgroundColor = color; }}
El color de fondo aparece cuando el puntero se desplaza sobre el elemento de párrafo y desaparece cuando el puntero se mueve fuera.
Pasando valores a una directiva de atributo
Esta sección te guía a través de establecer el color de resaltado mientras aplicas HighlightDirective.
En
highlight.directive.ts, importaInputdesde@angular/core.src/app/highlight.directive.ts (importaciones)
import {Directive, ElementRef, HostListener, inject, input} from '@angular/core';@Directive({ selector: '[appHighlight]',})export class HighlightDirective { private el = inject(ElementRef); appHighlight = input(''); @HostListener('mouseenter') onMouseEnter() { this.highlight(this.appHighlight() || 'red'); } @HostListener('mouseleave') onMouseLeave() { this.highlight(''); } private highlight(color: string) { this.el.nativeElement.style.backgroundColor = color; }}Añade una propiedad
inputappHighlight.src/app/highlight.directive.ts
import {Directive, ElementRef, HostListener, inject, input} from '@angular/core';@Directive({ selector: '[appHighlight]',})export class HighlightDirective { private el = inject(ElementRef); appHighlight = input(''); @HostListener('mouseenter') onMouseEnter() { this.highlight(this.appHighlight() || 'red'); } @HostListener('mouseleave') onMouseLeave() { this.highlight(''); } private highlight(color: string) { this.el.nativeElement.style.backgroundColor = color; }}La función
input()añade metadatos a la clase que hace que la propiedadappHighlightde la directiva esté disponible para enlace.En
app.component.ts, añade una propiedadcoloralAppComponent.Para aplicar simultáneamente la directiva y el color, usa enlace de propiedad con el selector de directiva
appHighlight, estableciéndolo igual acolor.src/app/app.component.html (color)
<h1>My First Attribute Directive</h1><h2>Pick a highlight color</h2><div> <input type="radio" name="colors" (click)="color='lightgreen'">Green <input type="radio" name="colors" (click)="color='yellow'">Yellow <input type="radio" name="colors" (click)="color='cyan'">Cyan</div><p [appHighlight]="color">Highlight me!</p><p [appHighlight]="color" defaultColor="violet"> Highlight me too!</p><hr><h2>Mouse over the following lines to see fixed highlights</h2><p [appHighlight]="'yellow'">Highlighted in yellow</p><p appHighlight="orange">Highlighted in orange</p><hr><h2>ngNonBindable</h2><p>Use ngNonBindable to stop evaluation.</p><p ngNonBindable>This should not evaluate: {{ 1 + 1 }}</p><h3>ngNonBindable with a directive</h3><div ngNonBindable [appHighlight]="'yellow'">This should not evaluate: {{ 1 +1 }}, but will highlight yellow.</div>El enlace de atributo
[appHighlight]realiza dos tareas:- Aplica la directiva de resaltado al elemento
<p> - Establece el color de resaltado de la directiva con un enlace de propiedad
- Aplica la directiva de resaltado al elemento
Estableciendo el valor con entrada de usuario
Esta sección te guía a través de añadir botones de radio para vincular tu elección de color a la directiva appHighlight.
Añade marcado a
app.component.htmlpara elegir un color de la siguiente manera:src/app/app.component.html (v2)
<h1>My First Attribute Directive</h1><h2>Pick a highlight color</h2><div> <input type="radio" name="colors" (click)="color='lightgreen'">Green <input type="radio" name="colors" (click)="color='yellow'">Yellow <input type="radio" name="colors" (click)="color='cyan'">Cyan</div><p [appHighlight]="color">Highlight me!</p><p [appHighlight]="color" defaultColor="violet"> Highlight me too!</p><hr><h2>Mouse over the following lines to see fixed highlights</h2><p [appHighlight]="'yellow'">Highlighted in yellow</p><p appHighlight="orange">Highlighted in orange</p><hr><h2>ngNonBindable</h2><p>Use ngNonBindable to stop evaluation.</p><p ngNonBindable>This should not evaluate: {{ 1 + 1 }}</p><h3>ngNonBindable with a directive</h3><div ngNonBindable [appHighlight]="'yellow'">This should not evaluate: {{ 1 +1 }}, but will highlight yellow.</div>Revisa
AppComponent.colorpara que no tenga valor inicial.En
highlight.directive.ts, revisa el métodoonMouseEnterpara que primero trate de resaltar conappHighlighty recurra aredsiappHighlightesundefined.src/app/highlight.directive.ts (mouse-enter)
import {Directive, ElementRef, HostListener, inject, input} from '@angular/core';@Directive({ selector: '[appHighlight]',})export class HighlightDirective { private el = inject(ElementRef); appHighlight = input(''); @HostListener('mouseenter') onMouseEnter() { this.highlight(this.appHighlight() || 'red'); } @HostListener('mouseleave') onMouseLeave() { this.highlight(''); } private highlight(color: string) { this.el.nativeElement.style.backgroundColor = color; }}Ejecuta tu aplicación para verificar que el usuario puede elegir el color con los botones de radio.

Enlazando a una segunda propiedad
Esta sección te guía a través de configurar tu aplicación para que el desarrollador pueda establecer el color por defecto.
Añade una segunda propiedad
Input()aHighlightDirectivellamadadefaultColor.src/app/highlight.directive.ts (defaultColor)
import {Directive, ElementRef, HostListener, inject, input} from '@angular/core';@Directive({ selector: '[appHighlight]',})export class HighlightDirective { private el = inject(ElementRef); defaultColor = input(''); appHighlight = input(''); @HostListener('mouseenter') onMouseEnter() { this.highlight(this.appHighlight() || this.defaultColor() || 'red'); } @HostListener('mouseleave') onMouseLeave() { this.highlight(''); } private highlight(color: string) { this.el.nativeElement.style.backgroundColor = color; }}Revisa el
onMouseEnterde la directiva para que primero trate de resaltar conappHighlight, luego condefaultColor, y finalmente conredsi ambas propiedades sonundefined.src/app/highlight.directive.ts (mouse-enter)
import {Directive, ElementRef, HostListener, inject, input} from '@angular/core';@Directive({ selector: '[appHighlight]',})export class HighlightDirective { private el = inject(ElementRef); defaultColor = input(''); appHighlight = input(''); @HostListener('mouseenter') onMouseEnter() { this.highlight(this.appHighlight() || this.defaultColor() || 'red'); } @HostListener('mouseleave') onMouseLeave() { this.highlight(''); } private highlight(color: string) { this.el.nativeElement.style.backgroundColor = color; }}Para enlazar a
AppComponent.colory usar "violet" como el color por defecto, añade el siguiente HTML. En este caso, el enlacedefaultColorno usa corchetes,[], porque es estático.src/app/app.component.html (defaultColor)
<h1>My First Attribute Directive</h1><h2>Pick a highlight color</h2><div> <input type="radio" name="colors" (click)="color='lightgreen'">Green <input type="radio" name="colors" (click)="color='yellow'">Yellow <input type="radio" name="colors" (click)="color='cyan'">Cyan</div><p [appHighlight]="color">Highlight me!</p><p [appHighlight]="color" defaultColor="violet"> Highlight me too!</p><hr><h2>Mouse over the following lines to see fixed highlights</h2><p [appHighlight]="'yellow'">Highlighted in yellow</p><p appHighlight="orange">Highlighted in orange</p><hr><h2>ngNonBindable</h2><p>Use ngNonBindable to stop evaluation.</p><p ngNonBindable>This should not evaluate: {{ 1 + 1 }}</p><h3>ngNonBindable with a directive</h3><div ngNonBindable [appHighlight]="'yellow'">This should not evaluate: {{ 1 +1 }}, but will highlight yellow.</div>Como con los componentes, puedes agreg múltiples enlaces de propiedad de directiva a un elemento host.
El color por defecto es rojo si no hay enlace de color por defecto. Cuando el usuario elige un color, el color seleccionado se convierte en el color de resaltado activo.
Desactivando el procesamiento de Angular con NgNonBindable
Para prevenir la evaluación de expresiones en el navegador, añade ngNonBindable al elemento host.
ngNonBindable desactiva la interpolación, directivas y enlace en plantillas.
En el siguiente ejemplo, la expresión {{ 1 + 1 }} se renderiza tal como está en tu editor de código, y no muestra 2.
src/app/app.component.html
<h1>My First Attribute Directive</h1><h2>Pick a highlight color</h2><div> <input type="radio" name="colors" (click)="color='lightgreen'">Green <input type="radio" name="colors" (click)="color='yellow'">Yellow <input type="radio" name="colors" (click)="color='cyan'">Cyan</div><p [appHighlight]="color">Highlight me!</p><p [appHighlight]="color" defaultColor="violet"> Highlight me too!</p><hr><h2>Mouse over the following lines to see fixed highlights</h2><p [appHighlight]="'yellow'">Highlighted in yellow</p><p appHighlight="orange">Highlighted in orange</p><hr><h2>ngNonBindable</h2><p>Use ngNonBindable to stop evaluation.</p><p ngNonBindable>This should not evaluate: {{ 1 + 1 }}</p><h3>ngNonBindable with a directive</h3><div ngNonBindable [appHighlight]="'yellow'">This should not evaluate: {{ 1 +1 }}, but will highlight yellow.</div>
Aplicar ngNonBindable a un elemento detiene el enlace para los elementos hijos de ese elemento.
Sin embargo, ngNonBindable aún permite que las directivas funcionen en el elemento donde aplicas ngNonBindable.
En el siguiente ejemplo, la directiva appHighlight sigue activa pero Angular no evalúa la expresión {{ 1 + 1 }}.
src/app/app.component.html
<h1>My First Attribute Directive</h1><h2>Pick a highlight color</h2><div> <input type="radio" name="colors" (click)="color='lightgreen'">Green <input type="radio" name="colors" (click)="color='yellow'">Yellow <input type="radio" name="colors" (click)="color='cyan'">Cyan</div><p [appHighlight]="color">Highlight me!</p><p [appHighlight]="color" defaultColor="violet"> Highlight me too!</p><hr><h2>Mouse over the following lines to see fixed highlights</h2><p [appHighlight]="'yellow'">Highlighted in yellow</p><p appHighlight="orange">Highlighted in orange</p><hr><h2>ngNonBindable</h2><p>Use ngNonBindable to stop evaluation.</p><p ngNonBindable>This should not evaluate: {{ 1 + 1 }}</p><h3>ngNonBindable with a directive</h3><div ngNonBindable [appHighlight]="'yellow'">This should not evaluate: {{ 1 +1 }}, but will highlight yellow.</div>
Si aplicas ngNonBindable a un elemento padre, Angular desactiva la interpolación y el enlace de cualquier tipo, como enlace de propiedad o enlace de evento, para los hijos del elemento.