Angular’s exportAs
syntax is a powerful tool that allows developers to expose directive instances to the template, providing fine-grained control over component and directive functionality. This guide will cover what exportAs
is, how it works, its syntax, and practical examples to help you leverage this feature in your Angular applications.
What is exportAs
in Angular?
The exportAs
property is a decorator option for Angular directives and components that allows you to assign a unique identifier (or alias) to a directive. This identifier can then be used in the template to access the directive’s instance and its properties or methods. This capability provides a way to interact directly with directives or components in the template, enhancing reusability and interactivity in Angular applications.
Why Use exportAs
?
The exportAs
property offers several benefits:
- Template Access: Gain direct access to directive methods and properties from the template, making it easier to control behavior.
- Enhanced Reusability: Allows you to expose directive features without additional wrapper components.
- Simplified Code: Reduces the need for complex event bindings by allowing you to interact directly with directives.
The exportAs
property is commonly used in Angular Material components, Angular Forms, and custom directives.
Syntax of exportAs
To use exportAs
, define it in the directive or component’s decorator options. Here’s the basic syntax:
typescriptCopy codeimport { Directive } from '@angular/core';
@Directive({
selector: '[appMyDirective]',
exportAs: 'myDirective' // Define alias here
})
export class MyDirective {
// Directive logic here
}
In this example:
exportAs: 'myDirective'
allows us to reference the directive with#myDirective="myDirective"
in the template.myDirective
is now an alias that can be used to access the directive’s properties and methods directly in the template.
Using exportAs
in Angular Templates
To access a directive or component instance with exportAs
, use a local template variable. Here’s a basic example:
Example 1: Creating and Accessing a Custom Directive
Let’s create a custom directive that changes an element’s background color and exposes a method to toggle this color.
Step 1: Generate the Directive
Use Angular CLI to generate the directive:
bashCopy codeng generate directive highlight
Step 2: Define the Directive Logic
Add exportAs
and some basic functionality in highlight.directive.ts
:
typescriptCopy codeimport { Directive, ElementRef, Renderer2, HostListener } from '@angular/core';
@Directive({
selector: '[appHighlight]',
exportAs: 'highlight' // Exposing directive instance
})
export class HighlightDirective {
private isHighlighted = false;
constructor(private el: ElementRef, private renderer: Renderer2) {}
toggleHighlight(color: string = 'yellow') {
this.isHighlighted = !this.isHighlighted;
const bgColor = this.isHighlighted ? color : '';
this.renderer.setStyle(this.el.nativeElement, 'backgroundColor', bgColor);
}
}
toggleHighlight()
toggles the background color between a specified color and the default.exportAs: 'highlight'
makes the directive instance available under the namehighlight
.
Step 3: Using the Directive in a Template
In the template, create a local reference using the alias highlight
and call the toggleHighlight()
method:
htmlCopy code<div appHighlight #highlight="highlight">
Highlight me!
</div>
<button (click)="highlight.toggleHighlight('lightblue')">Toggle Highlight</button>
Here’s what’s happening:
#highlight="highlight"
assigns a local reference to the directive instance.- The
toggleHighlight
method is called directly on the directive instance from the button click, which toggles the background color of thediv
.
Example 2: Using exportAs
with Angular Forms
Angular’s NgForm
directive provides a useful real-world example of exportAs
. The NgForm
directive, which is automatically applied to forms, is accessible via exportAs: 'ngForm'
. This allows us to access the form’s properties, like validity and value, directly in the template.
htmlCopy code<form #myForm="ngForm" (ngSubmit)="onSubmit(myForm)">
<input name="username" ngModel required />
<button type="submit" [disabled]="!myForm.valid">Submit</button>
</form>
<p *ngIf="!myForm.valid">Form is invalid!</p>
In this example:
#myForm="ngForm"
makes theNgForm
instance available in the template.myForm.valid
is used to disable the submit button when the form is invalid, providing a way to validate the form directly in the template.
Example 3: Creating a Modal Directive with exportAs
Let’s create a modal component that can be opened or closed programmatically using exportAs
.
Step 1: Create the Modal Component
Generate a new component for the modal:
bashCopy codeng generate component modal
Step 2: Define the Modal Logic with exportAs
In modal.component.ts
, add properties and methods to control the modal state:
typescriptCopy codeimport { Component, HostBinding } from '@angular/core';
@Component({
selector: 'app-modal',
template: `
<div class="modal-content">
<ng-content></ng-content>
<button (click)="close()">Close</button>
</div>
`,
styleUrls: ['./modal.component.css'],
exportAs: 'appModal' // Expose modal instance
})
export class ModalComponent {
@HostBinding('class.open') isOpen = false;
open() {
this.isOpen = true;
}
close() {
this.isOpen = false;
}
}
open()
andclose()
methods control theisOpen
state, which toggles a CSS class for modal visibility.exportAs: 'appModal'
allows us to refer to this component instance in the template.
Step 3: Using the Modal Component in a Template
In the parent component, add a reference to the modal instance and use the open
and close
methods.
htmlCopy code<app-modal #modal="appModal">
<p>This is the modal content!</p>
</app-modal>
<button (click)="modal.open()">Open Modal</button>
With #modal="appModal"
, we create a local reference to the modal instance, allowing us to call modal.open()
to display the modal.
Example 4: Creating a Tooltip Directive
A tooltip is a common UI element that can benefit from exportAs
, as it needs to be shown or hidden based on user interaction.
Step 1: Generate the Tooltip Directive
bashCopy codeng generate directive tooltip
Step 2: Define the Tooltip Directive Logic
In tooltip.directive.ts
, implement tooltip behavior with exportAs
:
typescriptCopy codeimport { Directive, ElementRef, Renderer2, HostListener, Input } from '@angular/core';
@Directive({
selector: '[appTooltip]',
exportAs: 'tooltip'
})
export class TooltipDirective {
@Input('appTooltip') tooltipText: string = '';
private tooltipElement: HTMLElement | null = null;
constructor(private el: ElementRef, private renderer: Renderer2) {}
show() {
this.tooltipElement = this.renderer.createElement('span');
const text = this.renderer.createText(this.tooltipText);
this.renderer.appendChild(this.tooltipElement, text);
this.renderer.addClass(this.tooltipElement, 'tooltip');
this.renderer.appendChild(document.body, this.tooltipElement);
const hostPos = this.el.nativeElement.getBoundingClientRect();
this.renderer.setStyle(this.tooltipElement, 'top', `${hostPos.bottom + 5}px`);
this.renderer.setStyle(this.tooltipElement, 'left', `${hostPos.left}px`);
}
hide() {
if (this.tooltipElement) {
this.renderer.removeChild(document.body, this.tooltipElement);
this.tooltipElement = null;
}
}
}
show()
andhide()
methods control tooltip visibility.exportAs: 'tooltip'
allows you to reference and control the tooltip instance from the template.
Step 3: Using the Tooltip Directive
In a component, you can now show or hide the tooltip on demand:
htmlCopy code<button #tooltip="tooltip" appTooltip="This is a tooltip" (mouseenter)="tooltip.show()" (mouseleave)="tooltip.hide()">
Hover over me
</button>
This example allows you to control tooltip visibility directly in the template using the show
and hide
methods exposed by exportAs
.
Best Practices for Using exportAs
- Use Meaningful Aliases: Choose aliases that clearly describe the functionality of the directive or component. This improves readability and maintainability.
- Document Public Methods and Properties: Document methods and properties that will be used with
exportAs
so that other developers can understand the functionality easily. - Limit Template Interaction: Expose only essential methods and properties to prevent over-complicating the template logic.
- Use in Reusable Components and Directives:
exportAs
is particularly useful in components and directives that are intended for reuse across multiple templates.
The exportAs
syntax in Angular is a valuable tool that enhances component and directive reusability. By enabling access to directive or component instances directly in the template, exportAs
helps developers create modular, flexible Angular mobile apps and websites.