4

I'm using Bootstrap and Angular 2 (v4) for my webapp. I would like to listen to an element in a directive for visibility changes. My element has a parent that can hide its children with hidden-sm-up and I need to trigger a function each time it is hidden or displayed.

div.hidden-sm-up
   input.form-control(myDirective, type='number')

and in my directive:

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

export class myDirective {
    constructor(private element: ElementRef, private renderer: Renderer){

    }

    ngAfterViewInit(): void{
        // listen to visibility change here
    }
}
Nate
  • 7,606
  • 23
  • 72
  • 124

2 Answers2

6

ngDoCheck is run when change detection is run, therefore I think it's the right place if you want to monitor it instead of just get it once at component creation time:

@HostListener('window:resize')
ngDoCheck() {
  this.isVisible = this.element.nativeElement.offsetParent !== null;
}

There might be better option, like some events that are emitted somewhere, but for the general case ngDoCheck should work fine.

yurzui
  • 205,937
  • 32
  • 433
  • 399
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • 1
    Unfortunately `ngDoCheck` is not triggered when the browser is resized... – Nate Mar 28 '17 at 21:12
  • You can just add `@HostBinding('window:resize')` before `ngDoCheck()` and it will do. – Günter Zöchbauer Mar 28 '17 at 21:12
  • I don't know how to use HostBinding... Should I put `ngDoCheck` inside parenthesis? – Nate Mar 28 '17 at 21:16
  • I'm getting the following error: `Can't bind to 'window:resize' since it isn't a known property of 'input'` (Please note that I have imported HostBinding from core) – Nate Mar 28 '17 at 21:20
  • Can you please try to reproduce in Plunker. I can't make any sense of this error and my code. – Günter Zöchbauer Mar 28 '17 at 21:21
  • 2
    It should be `Hostlistener` instead of `HostBinding` – yurzui Mar 29 '17 at 05:03
  • @GünterZöchbauer will this cause layout thrashing? – cambunctious May 01 '20 at 16:28
  • @cambunctious I'm not sure what you mean by that exactly, but I'd say no. You might need to be careful what code you execute there, but in general I don't see a problem. – Günter Zöchbauer May 01 '20 at 18:08
  • 1
    @GünterZöchbauer My understanding on the topic is limited so maybe my question doesn't make sense. Does calling `offsetParent` in `ngDoCheck` force the browser to re-calculate layout? Seems like that could be problematic with the default change detection strategy. Or is the layout already calculated at that point? I understand that _modifying_ the DOM in `ngDoCheck` is probably bad. – cambunctious May 01 '20 at 20:13
  • @cambunctious I see now what you mean but I also don't know. – Günter Zöchbauer May 01 '20 at 21:41
0

I found nice blog regarding that. HostListener has visible event. https://netbasal.com/with-great-angular-components-comes-great-single-responsibility-5fa37c35ad20

Vugar Abdullayev
  • 1,852
  • 3
  • 21
  • 46