4

I am trying to use ngZone to update my pagination state once the zone is stable so that the component I am trying to paginate will be fully rendered, and I will get the correct scrollWidth from the renderer.

The way it is being used in Angular Material 2 code is this:

// Update the position once the zone is stable so that the overlay will be fully rendered
// before attempting to position it, as the position may depend on the size of the rendered
// content.
this._ngZone.onStable.asObservable().pipe(first()).subscribe(() => {
  this.updatePosition();
});

I do the same in my component and run my own method instead of 'this.updatePosition()'. This doesn't help me to get the latest rendered state though, it still runs too early.

What am I missing here? What is the correct way to use ngZone with onStable?

williwaw
  • 73
  • 1
  • 6
  • Can you provide example that shows your issue? – yurzui Oct 30 '17 at 18:57
  • No, I would have to stage my whole build to showcase this issue which I cannot do for privacy reasons. Otherwise there will be no significant delay on rendering and thus the issue that I am trying to solve will not resurface. – williwaw Oct 30 '17 at 19:32
  • @williwaw, read this article [Do you still think that NgZone (zone.js) is required for change detection in Angular?](https://blog.angularindepth.com/do-you-still-think-that-ngzone-zone-js-is-required-for-change-detection-in-angular-16f7a575afef) that explains `stable` notion – Max Koretskyi Oct 31 '17 at 05:37
  • @AngularInDepth.com Thank you, Maxim! That's a great article, I read it just yesterday. So basically you're trying to say that ngZone is already a part of Angular2 change detection mechanism, and I shouldn't use it directly, right? My issue is that I need to do something (check whether pagination is needed) when my component is fully rendered, but I cannot use any of the lifecycle hooks for that. So I was hoping ngZone could help with that. Otherwise my only option is to use setTimeout which I'd like to avoid. – williwaw Oct 31 '17 at 17:12
  • can you setup a minimalistic stackblitz demo? – Max Koretskyi Oct 31 '17 at 17:33
  • @AngularInDepth.com Ok, I created a demo here: http://plnkr.co/edit/6lAQsljaS3NK8DTyjqch?p=preview I was able to reproduce the issue I have in my build on several breakpoints, for instance on 920px. I made the app load a lot of web fonts to emulate the delay. – williwaw Nov 01 '17 at 18:25
  • @AngularInDepth.com Now even when the font allows the user to see all content in the navigation bar, you will still see the message 'pagination arrows are needed' in the console. And there will be discrepancy between the logged scrollWidth and the actual scrollWidth of the ul element that I am trying to paginate (it can be checked by selecting a ul in dev tools and then using $0.scrollWidth in the console). – williwaw Nov 01 '17 at 18:27
  • @AngularInDepth.com Hope this clearly shows the issue that I am facing. I need a way to get the correct scrollWidth once I am sure that the component is fully rendered. – williwaw Nov 01 '17 at 18:28
  • @yurzui I provided an example that shows an issue. – williwaw Nov 01 '17 at 18:39
  • @williwaw, not really sure what you mean, but if I add `setTimeout(()=>{console.log(this.list.scrollWidth);}, 2000);` it will log the same value as from `ngAfterViewInit` so even if you have some discrepancy it's unlikely to come from Angular since the `scrollWidth` is the same with `setTimeout` which ensures everything is rendered – Max Koretskyi Nov 02 '17 at 07:48

1 Answers1

1
// Update the position once the zone is stable so that the overlay will be fully rendered
// before attempting to position it, as the position may depend on the size of the rendered
// content.

let that = this;

that.updatePosition();
Samuil Petrov
  • 542
  • 1
  • 13
  • 24
sangamesh
  • 19
  • 2