kkern kkern - 3 months ago 1094
Javascript Question

How to get width of (DOM) Element in Angular2

there a some similiar threads but I couldn't find a suitable answer
for my needs. So that direct DOM access should be strictly avoided
in angular2 I'm just wondering whats best practice for this.

What I wan't to achieve is a resize of a element based on the current width.

workitemresize.component.ts

import { Directive, ElementRef, HostListener, Renderer, Input } from '@angular/core';

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

export class WorkItemResizeDirective implements ngAfterViewInit {

private el: HTMLElement;
private renderer: Renderer;

constructor(el: ElementRef, public renderer: Renderer)
{
this.el = el.nativeElement;
this.renderer = renderer;
}


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

ngAfterViewInit() {
this.resizeWorks();
}

private resizeWorks(): void {
this.renderer.setElementStyle(this.el, 'height', this.el.width); // <-- doesn't work I kow that this.el.width doesn't exist but just for demonstration purpose
this.renderer.setElementStyle(this.el, 'height', '500'); // <-- works
}

}


projects.template.html

<div class="posts row">
<div class="work-item col-xs-12 col-sm-6 col-no-padding" workItemResize *ngFor="let post of posts">

<!-- show some fancy image -->
<div class="img" [ngStyle]="{'background-image':'url('+post.better_featured_image.source_url+')'}"></div>

</div>
</div>


Related:
https://github.com/angular/angular/issues/6515

Answer

I don't know a way to get the width from the host element without accessing nativeElement but setting could be done like:

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

@HostBinding('style.height.px')
elHeight:number;

private resizeWorks(): void {
  this.elHeight = this.el.nativeElement.width;
}

If you can add an element inside your components template like

<div style="width: 100%;" #div (window:resize)="elHeight = div.getBoundingClientRect()">
  <!-- your template here -->
</div>

then this would work without direct DOM access at all (but not after init).

Comments