GEDOPLAN
zero

Angular, Directive Composition

zero
blockchain 8244279 640 jpg

Direktiven sind ein mächtiges Werkzeug bei der Entwicklung mit Angular, um diverse Problemstellungen generisch und wiederverwendbar zu implementieren. Ein Feature, welches genau diese Idee unterstützt und zumindest für “standalone-Komponenten” verwendet werden kann, ist die Directive Composition API. Hier lassen sich grob zwei Anwendungsfälle unterscheiden

a) eine Komponente soll immer eine bestimmte Direktive erhalten

@Component({
  selector: 'app-directive-composition',
  standalone: true,
  imports: [MatTooltip],
  hostDirectives: [
    MatTooltip
  ],
  templateUrl: './directive-composition.component.html',
  styleUrl: './directive-composition.component.scss'
})
export class DirectiveCompositionComponent {
  constructor(private matTooltip: MatTooltip) {
    matTooltip.message = 'Component ToolTip'
  }
}

Unsere Komponente erhält damit nun automatisch die in hostDirective deklarierten Direktiven und kann sich diese im Konstruktor injizieren lassen. Ohne dieses Vorgehen müsste bei jeder Verwendung dieser Komponente sichergestellt werden, dass die Direktive auf dem Host deklariert ist:

<app-directive-composition mat-tooltip>

b) eine Direktive soll eine bestehende Direktive (oder mehrere) erweitern

Ein typisches Beispiel wäre folgendes: ein Mat-Tooltip soll angezeigt werden, aber generell nur unter bestimmten Bedingungen (z.B. nur, wenn er wirklich benötigt wird, der Inhalt also abgeschnitten wird). Anstatt nun bei jeder Verwendung eine entsprechende Prüfung per Property ([matTooltipDisabled]) zu setzen erlaubt uns die Directive Composition eine “Komposition” zu erstellen, also eine eigene Direktive die, ähnlich wie bei der Komponente oben, automatisch andere Direktiven instanziiert und an den Host bindet

@Directive({
    selector: '[appShowToolTipIfTruncated]',
    standalone: true,
    host: {
      '[style.white-space]': '"nowrap"',
      '[style.overflow]': '"hidden"',
      '[style.text-overflow]': '"ellipsis"'
    },
    hostDirectives: [MatTooltip]
  })
  export class ShowToolTipIfTruncatedDirective implements AfterViewChecked {
  
    constructor(private el: ElementRef, private matTooltip: MatTooltip) {
    }
  
    ngAfterViewChecked() {
      const textContent = this.el.nativeElement.textContent;
      this.matTooltip.message = textContent;
      this.matTooltip.disabled = this.calculateTextContentWith() < this.el.nativeElement.clientWidth;
    }
  
    private calculateTextContentWith(): number {
      const elementStyle = getComputedStyle(this.el.nativeElement);
      const canvas = document.createElement('canvas') as HTMLCanvasElement;
      const context = canvas.getContext('2d');
      context!.font = elementStyle.getPropertyValue('font');
      return context!.measureText(this.el.nativeElement.innerHTML).width;
    }
 
  }

Eine tolle weitere Möglichkeit wiederverwendbaren und gut wartbaren Code zu schreiben.

Code? Hab’ ich. github.com/GEDOPLAN/ng16-ng17

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Bitte füllen Sie dieses Feld aus.
Bitte füllen Sie dieses Feld aus.
Bitte gib eine gültige E-Mail-Adresse ein.
Sie müssen den Bedingungen zustimmen, um fortzufahren.

Autor

Diesen Artikel teilen

LinkedIn
Xing

Gibt es noch Fragen?

Fragen beantworten wir sehr gerne! Schreibe uns einfach per Kontaktformular.

Kurse

weitere Blogbeiträge

Work Life Balance. Jobs bei Gedoplan

We are looking for you!

Lust bei GEDOPLAN mitzuarbeiten? Wir suchen immer Verstärkung – egal ob Entwickler, Dozent, Trainerberater oder für unser IT-Marketing! Schau doch einfach mal auf unsere Jobseiten! Wir freuen uns auf Dich!

Work Life Balance. Jobs bei Gedoplan

We are looking for you!

Lust bei GEDOPLAN mitzuarbeiten? Wir suchen immer Verstärkung – egal ob Entwickler, Dozent, Trainerberater oder für unser IT-Marketing! Schau doch einfach mal auf unsere Jobseiten! Wir freuen uns auf Dich!