Dyrektywy

Angular ma trzy rodzaje dyrektyw:

  • komponenty - dyrektywy z szablonem,

  • dyrektywy strukturalne - zmieniają układ DOM-u dodając oraz usuwając jego elementy, na przykład *ngFor, *ngIf,

  • dyrektywy atrybutu - zmieniają wygląd oraz zachowanie elementów DOM, komponentów czy też innych dyrektyw.

Dyrektywy atrybutu

Dyrektywa atrybutu (ang. attribute directive) pozwala uzyskać dostęp do natywnego elementu DOM-u i dokonać jego modyfikacji.

Najpopularniejszą dyrektywą atrybytu jest ngStyle, która służy do manipulacji stylami elementu.

<div [ngStyle]="{'style-name': styleValue}">
 <!-- ... -->
</div>

podstawy

Dyrektywy podobnie jak komponenty mają swoje selektory. Definiujemy je podając metadane do dekoratora @Directive.

Ważnym szczegółem jest konieczność otoczenia nazwy dyrektywy kwadratowymi nawiasami [] aby mógł on być używany jako atrybut.

@Directive({ 
    selector: '[appAutoFocus]' 
})
export class AutoFocusDirective {}

Dostęp do elementu uzyskujemy w konstruktorze, który jako parametr otrzymuje obiekty typu ElementRef.

@Directive({ 
    selector: '[appAutoFocus]' 
})
export class AutoFocusDirective {

    constructor(element: ElementRef) {
        //...
    }

}

cykl życia

W dyrektywie podobnie jak w komponencie możemy skorzystać z uchwytów do jego cyklu życia. Aby to zrobić poprostu je implementujemy.

@Directive({ 
    selector: '[appAutoFocus]' 
})
export class AutoFocusDirective implements AfterViewInit {

    constructor(element: ElementRef) {
        //...
    }

    ngAfrterViewInit () {
        //...
    }

}

dodatkowe parametry

Mamy również możliwość definiowania dodatkowych parametrów dyrektyw. Ponownie, podobnie jak w komponentach, korzystamy z @Input.

@Directive({ 
    selector: '[appAutoFocus]' 
})
export class AutoFocusDirective implements AfterViewInit {

    @Input('appAutoFocusActive') isActive: boolean;

    constructor(element: ElementRef) {
        //...
    }

    ngAfrterViewInit () {
        //...
    }

}

wykorzystanie

Aby wykorzystać naszą dyrektywę umieszczamy ją w wybranym elemencie szablonu.

<md-input-container>
  <input mdInput
    [(ngModel)]="searchPhrase"
    [disabled]="!isActive"
    appAutoFocus
    [appAutoFocusActive]="isActive"
    type="text"
    placeholder="Search..."
  >
</md-input-container>

- - -

Zbudujemy swoją dyrektywę, która będzie ustawiała focus na naszą wyszukiwarkę piw kiedy stanie się ona aktywna.

Przykłady: beers-search.component.html, auto-focus.directive.ts v28

Dyrektywy strukturalne

Dyrektywy strukturalne (ang. structural directive) służą do manipulowania układem elementów widoku. Zazwyczaj poprzez dodawanie, usuwanie oraz modyfikowanie elementów DOM.

Najpopularniejszymi przykładami są *ngIf oraz *ngFor.

przedrostek *

Dyrektywę strukturalną łatwo rozpoznać dzięki przedrostkowi *. Nie jest to jednak jedynie konwencja ale uproszczona notacja, którą Angular tłumaczy na element <ng-template>.

*ngIf

Aby zobaczyć co dzieje się pod maską przyjrzymy się bliżej dyrektywie *ngIf.

<div *ngIf="condition">
    <!-- ... -->
</div>

Gdy kompilator widzi taki zapis zamienia go na atrybut tempate.

<div template="ngIf condition">
    <!-- ... -->
</div>

Kolejnym krokiem jest zamiana na <ng-tempalte> z prostym przypisaniem atrybutu [ngIf].

<ng-template [ngIf]="conditin">
    <div>
        <!-- ... -->
    </div>
</ng-template>

W tym momencie *ngIf ma już proste zadanie i działa dokładnie tak jak dyrektywa atrybutu, która umieszcza bądź usuwa swoją zawartość w elemencie <ng-tempalte>.

Aby móc dokonać tej manipulacji potrzebujemy dostp do elementów reprezentujących:

Implementacja *ngIf może wyglądać następująco:

@Directive({
  selector: '[ngIf]'
})
export class NgIfDirective {

  @Input() set ngIf (condition: boolean) {
    if (condition) {
      this.viewContainer.createEmbeddedView(this.templateRef);
    } else {
      this.viewContainer.clear();
    }
  }

  constructor(
    private templateRef: TemplateRef<any>,
    private viewContainer: ViewContainerRef
  ) {}

}

Można więc powiedzieć, że Angular jest napisany w Angular-ze.

Dla zainteresowanych: Nir Kaufman - Demystified Angular Directives (JS-Poland 2017)


Źródła

results matching ""

    No results matching ""