Home > front end >  Angular: How to get the offset height of an element after full rendering?
Angular: How to get the offset height of an element after full rendering?

Time:05-11

I need to get the offsetHeight of a div in order to set the max-height.px of another div to make it scrollable on content overflow-y.

The problem is that when I get the offsetHeight of the div, it has not completed the rendering and therefore returns 0 the first time. Then, by scrolling the page and clicking here and there, it gets re-rendered with the correct max-height value.

How can I wait/monitor for the first div to be fully rendered before returning the offsetHeight value?

Here is my code:

<tbody>
<tr *ngFor="let asset of assets; trackBy: trackByID">
    <td>{{asset.name}}</td>
    <td>
        <div [id]="asset.id   '.description'" #description >{{asset.description}}</div>
    </td>
    <td>
        <div  [style.max-height.px]="getOffsetHeight(description)">A details table goes here<div>
    </td>
</tr>
</tbody>

public trackByID(index: number, asset: AssetMgm) {
    return asset.id;
}

public getOffsetHeight(htmlElement: HTMLElement): number {
    if (htmlElement) {
        return htmlElement.offsetHeight;
    }else {
        return 0;
    }
}

CodePudding user response:

you can use ViewChildren and check in the ngAfterViewInit equal the value. For this you need know the "description" and the "detail"

<td>
    <div #description >{{asset.description}}</div>
</td>
<td>
    <div #detail>A details table goes here</div>
</td>

@ViewChildren('description') descriptions:QueryList<ElementRef>
@ViewChildren('detail') details:QueryList<ElementRef>

  ngAfterViewInit()
  {

    this.descriptions.changes.pipe(
      startWith(null)
    ).subscribe(_=>{
      console.log(this.descriptions.length)
      this.descriptions.forEach((x:ElementRef,index:number)=>{
        const detail=this.details.find((_,i:number)=>i==index)
        detail.nativeElement.style['max-height']=x.nativeElement.offsetHeight 'px'
      })

    })
  }

CodePudding user response:

I am not 100% sure it is a good solution because it is a bit dirty but I think you could do:

export class ... {
    ...
        @ViewChild('description ') description: ElementRef;
        offsetHeight = 0;
    ...
        ngOnInit(): void {
            setTimeout(() => {
                this.setOffsetHeight();
            }, 0);
        }
    
        public setOffsetHeight(): void {
            this.offsetHeight = !this.description.nativeElement?0:this.description.nativeElement.offsetHeight;
        }
    ...
}

And use offsetHeight inside the template:

<div  [style.max-height.px]="offsetHeight">A details table goes here</div>

*Note I closed the div properly, you forgot it

  • Related