Update Docs with directive

This commit is contained in:
francesco 2021-12-14 17:40:30 +01:00
parent 37754150e6
commit 9d14df3a3b
10 changed files with 145 additions and 3 deletions

View File

@ -0,0 +1,128 @@
# Directives
## Attribute vs Structural directives
<img src="../img/attribute_structural_directives.png" alt="attribute_structural_directives" width="800"/>
## Create basic attribute directives
Namingconvention: `name.directive.ts`
Generate it with the CLI:
```bash
ng generate directive <name>
# short:
ng g d <name>
```
<img src="../img/basic_directive.png" alt="basic_directive" width="550"/>
In `app.modules.ts` has to be added under `declarations` and *import* the source path to the directive.
Use it in the template.html with just adding the name `appBasicHighlight` to the component.
## Using Renderer for attribute directives
<img src="../img/renderer.png" alt="renderer" width="700"/>
Renderer is a better approach to accessing the DOM. Why? Because Angular dont works only in the Browser, but also with worker, which maight in certain circumstances will get errors.
## HostListener
With HostListener is a neat way to style the Element based on certain events triggered from the host (mouseover, mouseenter, mouseleave, etc).
<img src="../img/reactive_directive.png" alt="renderer" width="800"/>
## HostBinding
with HostBinding is the renderer no longer needed and is much simpler to change an elements backgroundcolor.
```ts
@Directive({
selector: '[appBetterHighlight]'
})
export class BetterHighlightDirective implements OnInit {
@HostBinding('style.backgroundColor') backgroundColor: string = 'transparent';
ngOnInit() {
}
@HostListener('mouseenter') mouseover(eventData: Event) {
this.backgroundColor = this.highlightColor;
}
@HostListener('mouseleave') mouseleave(eventData: Event) {
this.backgroundColor = this.defaultColor;
}
}
```
## Binding to directive properties
The hardcoded colors can be set from the outside using the `@Input` like so
```html
<p appBetterHighlight [defaultColor]="'yellow'" [highlightColor]="'blue'">bliblubla</p>
```
```ts
import {
Directive,
Renderer2,
OnInit,
ElementRef,
HostListener,
HostBinding,
Input
} from '@angular/core';
@Directive({
selector: '[appBetterHighlight]'
})
export class BetterHighlightDirective implements OnInit {
@Input() defaultColor: string = 'transparent';
@Input('appBetterHighlight') highlightColor: string = 'blue';
@HostBinding('style.backgroundColor') backgroundColor: string;
ngOnInit() {
this.backgroundColor = this.defaultColor;
}
@HostListener('mouseenter') mouseover(eventData: Event) {
this.backgroundColor = this.highlightColor;
}
@HostListener('mouseleave') mouseleave(eventData: Event) {
this.backgroundColor = this.defaultColor;
}
}
```
## Building a structural directive
```ts
import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';
@Directive({
selector: '[appUnless]'
})
export class UnlessDirective {
@Input() set appUnless(condition: boolean) {
if (!condition) {
this.vcRef.createEmbeddedView(this.templateRef);
} else {
this.vcRef.clear();
}
}
constructor(private templateRef: TemplateRef<any>, private vcRef: ViewContainerRef) { }
}
```
## ngSwitch
<img src="../img/ngSwitch.png" alt="ngSwitch" width="400"/>
ngSwitch can be used for replacing a lot of ngIf statements.

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 KiB

BIN
img/basic_directive.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 KiB

BIN
img/ngSwitch.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 337 KiB

BIN
img/reactive_directive.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 KiB

BIN
img/renderer.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 302 KiB

View File

@ -9,6 +9,7 @@ import { RecipeDetailComponent } from './recipes/recipe-detail/recipe-detail.com
import { RecipeItemComponent } from './recipes/recipe-list/recipe-item/recipe-item.component'; import { RecipeItemComponent } from './recipes/recipe-list/recipe-item/recipe-item.component';
import { ShoppingListComponent } from './shopping-list/shopping-list.component'; import { ShoppingListComponent } from './shopping-list/shopping-list.component';
import { ShoppingEditComponent } from './shopping-list/shopping-edit/shopping-edit.component'; import { ShoppingEditComponent } from './shopping-list/shopping-edit/shopping-edit.component';
import { DropdownDirective } from './shared/dropdown.directive';
@NgModule({ @NgModule({
declarations: [ declarations: [
@ -19,7 +20,8 @@ import { ShoppingEditComponent } from './shopping-list/shopping-edit/shopping-ed
RecipeDetailComponent, RecipeDetailComponent,
RecipeItemComponent, RecipeItemComponent,
ShoppingListComponent, ShoppingListComponent,
ShoppingEditComponent ShoppingEditComponent,
DropdownDirective
], ],
imports: [ imports: [
BrowserModule, BrowserModule,

View File

@ -9,7 +9,7 @@
<li><a href="#" (click)="onSelect('shopping-list')">Shopping List</a></li> <li><a href="#" (click)="onSelect('shopping-list')">Shopping List</a></li>
</ul> </ul>
<ul class="nav navbar-nav navbar-right"> <ul class="nav navbar-nav navbar-right">
<li class="dropdown"> <li class="dropdown" appDropdown>
<a href="#" class="dropdown-toggle" role="button">Manage <span class="caret"></span></a> <a href="#" class="dropdown-toggle" role="button">Manage <span class="caret"></span></a>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
<li><a href="#">Save Data</a></li> <li><a href="#">Save Data</a></li>

View File

@ -14,7 +14,7 @@
</div> </div>
<div class="row"> <div class="row">
<div class="col-xs-12"> <div class="col-xs-12">
<div class="btn-group"> <div class="btn-group" appDropdown>
<button <button
type="button" type="button"
class="btn btn-primary dropdown-toggle"> class="btn btn-primary dropdown-toggle">

View File

@ -0,0 +1,12 @@
import { Directive, HostListener, HostBinding } from '@angular/core';
@Directive({
selector: '[appDropdown]'
})
export class DropdownDirective {
@HostBinding('class.open') isOpen = false;
@HostListener('click') toggleOpen() {
this.isOpen = !this.isOpen;
}
}