I'm writing an Angular2 component that needs to dynamically change its content when resized. I am using the experimental Renderer in @angular/core (v2.1.0) and can wire up a click listener with the following:
this.rollupListener = this.renderer.listen(this.rollUp, 'click', (event) => {
...
});
But unfortunately I cannot do the same for a resize event - both 'resize' or 'onresize' do not work:
this.resizeListener = this.renderer.listen(this.container, 'resize', (event) => {
// this never fires :(
});
I am able to pick up on browser resize events using the following:
@HostListener('window:resize', ['$event.target'])
onResize() {
...
}
But unfortunately not all component resizing in my application is due to a browser resize.
Basically, I'm looking for the JQuery equivalent of:
$(this.container).resize(() => {
...
});
I ended up implementing a service that uses the element-resize-detector library (https://github.com/wnr/element-resize-detector). Couldn't find a TypeScript definition file but with a little help (Use element-resize-detector library in an Angular2 application), implemented the following:
element-resize-detector.d.ts
declare function elementResizeDetectorMaker(options?: elementResizeDetectorMaker.ErdmOptions): elementResizeDetectorMaker.Erd;
declare namespace elementResizeDetectorMaker {
interface ErdmOptions {
strategy?: 'scroll' | 'object';
}
interface Erd {
listenTo(element: HTMLElement, callback: (elem: HTMLElement) => void);
removeListener(element: HTMLElement, callback: (elem: HTMLElement) => void);
removeAllListeners(element: HTMLElement);
uninstall(element: HTMLElement);
}
}
export = elementResizeDetectorMaker;
resize.service.ts
import { Injectable } from '@angular/core';
import * as elementResizeDetectorMaker from 'element-resize-detector';
@Injectable()
export class ResizeService {
private resizeDetector: any;
constructor() {
this.resizeDetector = elementResizeDetectorMaker({ strategy: 'scroll' });
}
addResizeEventListener(element: HTMLElement, handler: Function) {
this.resizeDetector.listenTo(element, handler);
}
removeResizeEventListener(element: HTMLElement) {
this.resizeDetector.uninstall(element);
}
}
my-component.ts
import { Component } from '@angular/core';
import { ResizeService } from '../resize/index';
@Component({
selector: 'my-component',
template: ``
})
export class MyComponent {
constructor(private el: ElementRef, private resizeService: ResizeService) {
}
ngOnInit() {
this.resizeService.addResizeEventListener(this.el.nativeElement, (elem) => {
// some resize event code...
});
}
ngOnDestroy() {
this.resizeService.removeResizeEventListener(this.el.nativeElement);
}
}
This angular 7 library does a pretty good job: https://www.npmjs.com/package/angular-resize-event
<div (resized)="onResized($event)"></div>
import { Component } from '@angular/core';
// Import the resized event model
import { ResizedEvent } from 'angular-resize-event';
@Component({...})
class MyComponent {
width: number;
height: number;
onResized(event: ResizedEvent) {
this.width = event.newWidth;
this.height = event.newHeight;
}
}
I wrote this Angular2 directive to solve this.
You can install it by npm install bound-sensor
.
The advantage of using this method is it tells you once the size of parent of component changes and it doesn't depend on window resize! Imagine you need to expand and refresh your content base on size of its parent, this solves it easily.
As an alternative in order to be able to listen to a specific container that is resizing we can use
(window:resize)="onResize($event)"
in html
and in component in the method onResize(event: UIEvent)
you can do whatever you want on resize.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With