Directives
About 3 min
Directives
- A
directiveis essentially afunctionthat executes whenever the Angular compiler finds it in theTemplate Directivesare used to extend the power of theHTMLby adding newsyntax- A
componentis therefore a (more advanced)directive
Example
- The following
StackBlitzexample contains the most commondirectives:
Structural directives
Structural directivesare used to manipulate the DOM- They shape or reshape the DOM's structure, typically by adding, removing, or manipulating elements
- Easy recognizable by the asterisk (
*) prefix
| structural directive | example | purpose |
|---|---|---|
@if | @if(showFirstDiv) { ... } | Takes a boolean expression and makes an entire chunk of the DOM appear or disappear (NOT hidden) |
@else | @else { ... } | If the boolean expression returns false we add a the HTML within the else block |
@for | @for (n of names; track $index) { ... } | Adds the element(s) within the @for n-times to the DOM based on the amount of items in the list. The block of HTML acts as a template for rendering each item in the list |
@for (n of names; track $index; let i = $index,isFirst = $first, isLast = $last) { ... } | Values we can use as local variables withing the @for : index, count, first, last, even, odd |
@if: why removing instead of hiding?
- When the boolean expression in the
@ifdirectivereturns false, the entire element is removed from the DOM - Hiding the element would mean that all the
bindingsandeventsstill exist, although the element is invisible - This requires extra (unnecessary) resources from Angular (and thus the browser), which could slow down the application
@for aliases
- Within the
@fordirective we can access somevalueswhich could be interesting to know because we are working with aniteration - These
valuescan be aliased to local variableslet i = $index;:indexis thevalue,iis thelocal variablelet isFirst = $first:firstis thevalue,isFirstis thelocal variable- ...
@for : track $index
Track is a feature that helps Angular identify unique items in a collection, allowing it to track changes more efficiently and re-render only the elements that have been modified.
Track really comes into play when looping more complex objects, but we just add it by default right now!
Attribute directives
Attribute directiveslisten to and modify the behavior of otherHTML elements,attributes,properties, andcomponents
@switch
- The
@switchdirective is actually a set of cooperating directives:switch,case, anddefault
<div>
@switch (color) {
@case ('green') {
<div class="green">GREEN</div>
}
@case ('red') {
<div class="red">RED</div>
}
@case ('blue') {
<div class="blue">BLUE</div>
}
@default{
<div class="gray">DEFAULT</div>
}
}
</div>
@switchaccepts apropertyor aexpression@casechecks its value against the@switchvalue and returns the HTML when they are a match
single quotes in an expression
- There is a difference when using single quotes or not in an
expression @case('green'):expressionis just the stringgreen@case(green):expressionis the propertygreen
[ngClass]
- Add or remove several CSS classes simultaneously
- Based on a
boolean property:isSpecial
<div [ngClass]="isSpecial ? 'special' : ''">This div is special</div>
- Based on an
objectofclasses:currentClasses
<div [ngClass]="currentClasses">Current classes div</div>
Componentclass file
isSpecial: boolean = true;
currentClasses: {};
isLarge: boolean = true;
isError: boolean = false;
setCurrentClasses() {
// CSS classes based on business logic
this.currentClasses = {
large: this.isLarge,
error: this.isError
};
}
Â
Â
Â
Â
Â
Â
CSS
.special {
border: 2px dotted red;
}
.large {
font-size: 2rem;
}
.error {
color: red;
background-color: rgba(255, 0, 0, 0.1);
}
Add/remove single class
- To add or remove a single class, use
class bindingrather thanNgClass [class.sale]="onSale": addssaleclass to element ifonSaleexpressionis true
[ngStyle]
- Set many inline styles simultaneously and dynamically, based on the state of the component
<div [ngStyle]="currentStyles">Current styles div</div>
currentStyles: {};
isItalic: boolean = true;
isBold: boolean = false;
setCurrentStyles() {
// CSS inline styles based on business logic
this.currentStyles = {
"font-style": this.isItalic ? "italic" : "normal",
"font-weight": this.isBold ? "bold" : "normal"
};
}
Â
Â
Â
Â
Â
A component is a directive
- A
componentis adirective - This makes perfect sense because a
componentis loaded when defining theselectoras an HTML element in thetemplate- We are extending the power of the
HTML, because we add a complete new set of elements to the DOM
- We are extending the power of the
- Therefore a
componentis adirectivewith atemplate
Want proof? Check the source code!
- Go to the
node_module\@angular\core\index.d.tsfile and check thedeclarationof theComponent interface(line 1436):
/**
* Supplies configuration metadata for an Angular component.
*
* @publicApi
*/
export declare interface Component extends Directive {
/**
* The change-detection strategy to use for this component.
*
* When a component is instantiated, Angular creates a change detector,
* which is responsible for propagating the component's bindings.
* The strategy is one of:
* - `ChangeDetectionStrategy#OnPush` sets the strategy to `CheckOnce` (on demand).
* - `ChangeDetectionStrategy#Default` sets the strategy to `CheckAlways`.
*/
changeDetection?: ChangeDetectionStrategy;
...
Â
- The
Component interfaceextends adirective interface
Check it yourself
- Check the news app and find out where we already implemented some of these
directives
Exercise
Building on the stackblitz above implement the following features.
- Add a checkbox that binds to the showSecondDiv property so you can change this
- Create a dropdown that binds to the color property with options "green" and "blue"