How do I keep @HostListeners from overriding each other when extending classes?

1.5k views Asked by At

I'm building a class to extend all my components that listens to resize events like this

@HostListener( 'window:resize', ['$event'] ).....//function

In other components I listen to the same event, which causes one to override the other when the class is extended so only one triggers when the window size changes. I discovered this was the problem because I have one big class I un-comment to tinker with everything in one place. When I added this to the class

@HostListener( 'window:resize', ['$event'] ) reSize( event ){ this.calcScreen(); }
@HostListener( 'window:resize', ['$event'] ) reScale( event ){ this.checkScrn(); }

I got an error pointing at there being duplicates, which explains why they overridde one another when extended. I gave the functions different names to see if that would help and I think the second one is the one that took dominance. However with just one @HostListener with this on the end

reSize( event ){ this.calcScreen(); this.checkScrn(); }

they both run as desired.

How can I work around this problem? Here's my classes so far.

AppComponent

export class AppComponent extends GridFactory implements OnInit {
    MainFrame: SiteFrame;

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

    constructor( @Self() public appSpecs: ElementRef ){
        super( appSpecs );
    }

    ngOnInit(){ this.calcScreen(); }

    calcScreen(){ this.MainFrame = uiMonitor(); }
}

GridFactory

export class GridFactory implements AfterViewInit {
    ScreenCore   : ScrnCore  = new ScrnCore();
    GridSettings : GridSpecs = new GridSpecs();

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


    constructor( @Self() public appSpecs: ElementRef ){}

    ngAfterViewInit(){ this.checkScrn(); }

    checkScrn(){
        this.ScreenCore.Width   = this.appSpecs.nativeElement.offsetWidth;
        this.ScreenCore.Height  = this.appSpecs.nativeElement.offsetHeight;

        this.activteGrid( this.ScreenCore );
    }

    activteGrid( data: ScrnCore ){ this.GridSettings = gridManager( data.Width ); }
}

AppComponent (both combined as one class)

export class AppComponent implements OnInit, AfterViewInit{
    MainFrame    : SiteFrame = new SiteFrame();
    ScreenCore   : ScrnCore  = new ScrnCore();
    GridSettings : GridSpecs = new GridSpecs();

    @HostListener('window:resize', ['$event'])
    reSize(event){ this.calcScreen(); this.checkScrn(); }

    constructor( @Self() public appSpecs: ElementRef ){}

    ngOnInit(){ this.calcScreen(); }

    ngAfterViewInit(){ this.checkScrn(); }

    calcScreen(){ this.MainFrame = uiMonitor(); }

    checkScrn(){
        this.ScreenCore.Width   = this.appSpecs.nativeElement.offsetWidth;
        this.ScreenCore.Height  = this.appSpecs.nativeElement.offsetHeight;

        this.activteGrid( this.ScreenCore );
    }

    activteGrid( data: ScrnCore ){ this.GridSettings = gridManager( data.Width ); }
}
2

There are 2 answers

0
Optiq On BEST ANSWER

Turns out all I had to do was leave it like this in the AppComponent

@HostListener('window:resize', ['$event'])
reSize(event){ this.calcScreen(); this.checkScrn(); }

even though I don't have it defined on the AppComponent it still registers because I'm extending the GridFactory to it, which I instinctively assumed wouldn't work...... but it does :)

0
Eduard Void On

You can call methods from extended class by using super prefix.

So your app method should look like this:

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

This approach is avoiding code redundancy.