2017-10-20 30 views
1

J'essaie de créer une directive qui rendra mes mises en page pleines. Pour ce faire, je suis en utilisant le code ci-dessous:Propriétés de l'élément de requête ang 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); 
    } 
} 

Cela fonctionne bien, mais je veux une façon de ne pas coder en dur l'identifiant de pied de page. Cette directive sera utilisée sur des éléments qui ne sont pas liés au pied de page de quelque manière que je ne peux pas utiliser @ViewChild ou @Input. Je pensais que je créerais une autre directive pour obtenir cette information (hauteur de l'élément) et il ressemble à ceci:

@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; 
    } 
} 

Maintenant, je veux un moyen de transmettre ces données de hauteur de cette directive à la première directive qui fait les calculs.

Répondre

1

Tout d'abord, le this.el.nativeElement.style est l'attribut de style et non le style calculé. Si vous voulez obtenir des styles calculés, utilisez le bit 'window.getComputedStyle' pour le cas de hauteur si la hauteur sera par exemple auto cela donnera juste une chaîne 'auto'. Donc, si vous voulez une vraie hauteur calculée, utilisez this.el.nativeElement.offsetHeight ou this.el.nativeElement.clientHeight. Jetez un oeil à cette réponse pour plus d'informations: offsetHeight vs clienHeight.

J'ai créé un exemple pour ma solution de votre problème. Alors s'il vous plaît suivez le plunker link et regardez le code.

Le concept de base est que vous devriez avoir une sortie sur le premier composant et l'écouter depuis le second.

+0

Merci, juste ce que je cherchais. Cela fonctionne pour moi bien que j'ai plus tard eu recours à des observables pour transmettre des informations d'une directive à l'autre. Merci encore. –