I have a problem with this one.
I have a create a timeline to display schedule when vessels are supposed to dock on different terminals. it looks like that:
<ul class="vessels-schedule">
<li *ngFor="let terminal of terminals" class="mt-3">
<div class="terminal-schedule" #terminalSchedule #test>
<div class="terminal-information" #terminalInformation>
<h3 class="terminal-name">{{terminal.name}}</h3>
</div>
<div *ngFor="let date of dates" class="vessel-date" #vesselDate></div>
<div class="vessels">
<div *ngFor="let vessel of terminal.vessels; let index = index"
class="vessel"
[style.left.px]="getVesselPosition(vessel.estimateTimeArrival)"
tabindex="0" #vessel>
...
It renders a row by terminal + a grid for each day *ngFor="let date of dates"
and all vessels for this terminal positioned at the right date/time.
I have also a couples of ViewChild
to dynamically calculate position:
@ViewChildren('terminalSchedule') terminalSchedule: QueryList<ElementRef>;
@ViewChild('terminalInformation') terminalInformation: ElementRef;
@ViewChild('vesselDate') vesselDate: ElementRef;
@ViewChild('vessel') vessel: ElementRef;
...
ngAfterViewInit(): void {
this.terminalSchedule.changes.subscribe(item => {
if (this.terminalSchedule.length) {
this.terminalScheduleOffsetWidth = this.terminalSchedule.first.nativeElement.offsetWidth;
this.terminalInformationOffsetWidth = this.terminalInformation.nativeElement.offsetWidth;
this.vesselDateOffsetWidth = this.vesselDate.nativeElement.offsetWidth;
this.vesselOffsetWidth = this.vessel !== undefined ? this.vessel.nativeElement.offsetWidth : 0;
...
And a function to set the position that returns a pixel value.
I don't know if it's because I don't initialize it at the right place, but when I bind data I have this in the console (it works though!):
NG0100: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value for 'left': '0'. Current value: '301.5416666666667'.
I initialize the terminal list right in OnChanges():
ngOnChanges(): void {
...
this.getTerminal();
}
Also, in the complementary question, I try to figure the best approach for resizing. Right now, I change a boolean property on resize to force re-render, I don't know if it's a good idea...