2017-10-20 2 views
1

Ich versuche eine Direktive zu erstellen, die meine Layouts auf volle Höhe bringt. Um dies zu tun, ich den Code verwenden unter:Eigenschaften des dom-Elements abfragen Angular 4

import { HostListener, Directive, ElementRef, Input, AfterViewInit } from '@angular/core'; 
@Directive({ selector: '[fill-height]' }) 

export class FillHeightDirective implements AfterViewInit { 


    constructor(private el: ElementRef) { 
    } 

    ngAfterViewInit(): void { 
     this.calculateAndSetElementHeight(); 
    } 

    @HostListener('window:resize', ['$event']) 
    onResize(event) { 
     this.calculateAndSetElementHeight(); 
    } 

    private calculateAndSetElementHeight() { 
     this.el.nativeElement.style.overflow = 'auto'; 
     const windowHeight = window.innerHeight; 
     const elementOffsetTop = this.getElementOffsetTop(); 
     const elementMarginBottom = this.el.nativeElement.style.marginBottom; 
     const footerElementMargin = this.getfooterElementMargin(); 

     this.el.nativeElement.style.height = windowHeight - footerElementMargin - elementOffsetTop + 'px'; 
     console.log([windowHeight, elementOffsetTop, elementMarginBottom, footerElementMargin, this.el.nativeElement.style.height]); 
    } 

    private getElementOffsetTop() { 
     return this.el.nativeElement.getBoundingClientRect().top; 
    } 

    private getfooterElementMargin() { 
     const footerElement = document.getElementById('footer'); 
     const footerStyle = window.getComputedStyle(footerElement); 
     return parseInt(footerStyle.height, 10); 
    } 
} 

Dies funktioniert gut, aber ich möchte nicht einen Weg zu hart Code der Fußzeile ID. Diese Direktive wird für Elemente verwendet, die nicht mit der Fußzeile in Verbindung stehen, so dass ich @ViewChild oder @Input nicht verwenden kann. Ich dachte, dass ich eine andere Richtlinie schaffen würde diese Information (Elementhöhe) zu erhalten, und es sieht wie folgt aus:

@Directive({ selector: '[footer]' }) 

export class NbFooterDirective implements AfterViewInit { 

    constructor(private el: ElementRef) { 
    } 

    ngAfterViewInit(): void { 
     this.getElementHeight(); 
    } 

    @HostListener('window:resize', ['$event']) 
    onResize(event) { 
     this.getElementHeight(); 
    } 

    private getElementHeight() { 
     return this.el.nativeElement.style.height; 
    } 
} 

Jetzt i eine Art und Weise wollen von dieser Richtlinie an die erste Richtlinie diese Höhendaten zu übergeben, die die Berechnungen durchführt.

Antwort

1

Zunächst ist das this.el.nativeElement.style das Stilattribut und nicht der berechnete Stil. Wenn Sie berechnete Stile erhalten möchten, verwenden Sie das Bit "window.getComputedStyle" für den Fall der Höhe, wenn die Höhe zum Beispiel ist, dann gibt es nur eine Zeichenfolge 'auto'. Wenn Sie also eine tatsächlich berechnete Höhe wünschen, verwenden Sie this.el.nativeElement.offsetHeight oder this.el.nativeElement.clientHeight. Werfen Sie einen Blick auf diese Antwort für mehr: offsetHeight vs clienHeight.

Ich habe ein Beispiel für meine Lösung Ihres Problems erstellt. Bitte folgen Sie der plunker link und schauen Sie sich den Code an.

Das Grundkonzept ist, dass Sie eine Ausgabe auf der ersten Komponente haben und hören Sie diese von der zweiten Komponente.

+0

Danke, genau das, was ich gesucht habe. Das funktioniert für mich, obwohl ich später auf Observable zurückgreifen musste, um Informationen von einer Anweisung zur anderen zu übertragen. Danke noch einmal. –