Skip to content

fix(grid): fix zone.onStable patterns broken in zoneless change detection - 21.2.x#17454

Open
viktorkombov wants to merge 2 commits into
21.2.xfrom
vkombov/grid-zoneless-issues-21.2.x
Open

fix(grid): fix zone.onStable patterns broken in zoneless change detection - 21.2.x#17454
viktorkombov wants to merge 2 commits into
21.2.xfrom
vkombov/grid-zoneless-issues-21.2.x

Conversation

@viktorkombov

Copy link
Copy Markdown
Contributor

Closes #17364
Closes #17385
Closes #17318
Closes #17280

What

Grid virtualization, autosizing, and keyboard navigation relied on NgZone.onStable, which never emits in zoneless apps. As a result, scroll-driven chunkLoad, column autosize, filter-row rendering, and post-scroll cell activation silently never ran.

This migrates all of that off onStable and onto Angular’s render hooks.

Changes

Core

  • Added a new central helper: runAfterRenderOnce(injector, cb, phase?) in core/utils.ts.

    • This is now the single scheduling point for all deferred-render work.
    • Previously, this logic was scattered across onStable / ɵNoopNgZone branches.
  • Updated every affected call site to go through runAfterRenderOnce.

  • Removed the private ɵNoopNgZone-based zoneless detection.

  • Removed the duplicated per-class runAfterRender helpers.

Grids

  • IgxFilteringService.isFilterRowVisible is now signal-backed, so the OnPush header row re-renders without requiring a zone tick.
  • Filter cells now observe their own size via ResizeObserver to recompute visible chips after resize.
  • Column resize now explicitly notifies the grid via notifyResized, instead of relying on an empty zone.run.
  • Keyboard navigation now notifies after any scrolling navigation key, not just Ctrl.
  • Hierarchical navigation now subscribes to chunkLoad before scrolling, avoiding missed synchronous emissions.
  • Deferred work in for_of, grid-base, and pivot-grid was migrated to runAfterRenderOnce.

Tests

  • Added zoneless duplicates using provideZonelessChangeDetection for the affected grid, tree, hierarchical, and pivot suites.

  • Centralized async test helpers in helper-utils.spec.ts.

  • runAfterRenderOnce consumers now settle through shared helpers:

    • waitForGridSettle
    • setGridVerticalScrollTop
    • dispatchGridScrollEvents
    • navigateWithGridScroll
  • Updated the zoned originals to await the new render-boundary timing.

    • Previously, they happened to align with onStable.

Notes

  • Behavior for zoned apps is unchanged in practice.

    • Real interaction still triggers a render.
    • Only the timing signal moved from onStable to afterNextRender.
  • No runOutsideAngular was removed.

  • No forced detectChanges was added in zoneless tests.

Motivation / Context

Type of Change (check all that apply):

  • Bug fix
  • New functionality
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Refactoring (no functional changes)
  • Documentation
  • Demos
  • CI/CD
  • Tests
  • Changelog
  • Skills/Agents

Component(s) / Area(s) Affected:

How Has This Been Tested?

  • Unit tests
  • Manual testing
  • Automated e2e tests

Test Configuration:

  • Angular version:
  • Browser(s):
  • OS:

Screenshots / Recordings

Checklist:

  • All relevant tags have been applied to this PR
  • This PR includes unit tests covering all the new code (test guidelines)
  • This PR includes API docs for newly added methods/properties (api docs guidelines)
  • This PR includes feature/README.MD updates for the feature docs
  • This PR includes general feature table updates in the root README.MD
  • This PR includes CHANGELOG.MD updates for newly added functionality
  • This PR contains breaking changes
  • This PR includes ng update migrations for the breaking changes (migrations guidelines)
  • This PR includes behavioral changes and the feature specification has been updated with them
  • Accessibility (ARIA, keyboard navigation, focus management) has been verified

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates Ignite UI for Angular Grid/TreeGrid/HierarchicalGrid/PivotGrid internals to stop relying on NgZone.onStable (which doesn’t emit under zoneless change detection) and instead schedule deferred DOM/layout work via Angular render hooks, with accompanying zoneless regression coverage across affected specs.

Changes:

  • Added a centralized runAfterRenderOnce(injector, cb, phase?) helper and migrated multiple grid virtualization/autosize/scroll/activation scheduling call sites away from onStable.
  • Adjusted keyboard navigation to notify the grid after any scroll-causing navigation (not only Ctrl cases), improving activation of virtualized target cells.
  • Added/updated multiple unit tests (including new zoneless suites using provideZonelessChangeDetection) to validate virtualization, autosizing, filtering UI behavior, and navigation timing.

Reviewed changes

Copilot reviewed 23 out of 23 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
projects/igniteui-angular/core/src/core/utils.ts Adds runAfterRenderOnce helper using afterNextRender phases.
projects/igniteui-angular/directives/src/directives/for-of/for_of.directive.ts Migrates virtualization DOM updates/recalc scheduling to runAfterRenderOnce and fixes a reduce initial value edge case.
projects/igniteui-angular/grids/core/src/grid-navigation.service.ts Expands conditions for notifying grid changes after scroll-causing navigation keys.
projects/igniteui-angular/grids/grid/src/grid-base.directive.ts Replaces onStable/zoneless branching with runAfterRenderOnce for autosize and scroll-driven work.
projects/igniteui-angular/grids/pivot-grid/src/pivot-grid.component.ts Replaces onStable autosize scheduling with runAfterRenderOnce + requestAnimationFrame.
projects/igniteui-angular/test-utils/tree-grid-components.spec.ts Adds a Tree Grid host with many columns for horizontal virtualization/navigation tests.
projects/igniteui-angular/grids/tree-grid/src/tree-grid.component.spec.ts Updates an auto-generation test to async timing (whenStable/wait).
projects/igniteui-angular/grids/tree-grid/src/tree-grid-summaries.spec.ts Replaces time-based waits with whenStable and enables auto-detect changes in a scrolling test.
projects/igniteui-angular/grids/tree-grid/src/tree-grid-keyBoardNav.spec.ts Adds a zoneless keyboard navigation regression (virtualized target activation) and adjusts existing tests.
projects/igniteui-angular/grids/tree-grid/src/tree-grid-integration.spec.ts Adds a zoneless autosize alignment regression for horizontally constrained layouts.
projects/igniteui-angular/grids/hierarchical-grid/src/hierarchical-grid.virtualization.spec.ts Enables autoDetectChanges() for a scroll position regression test.
projects/igniteui-angular/grids/hierarchical-grid/src/hierarchical-grid.navigation.spec.ts Makes navigation waits deterministic (chunkLoad/activeNodeChange) and adds zoneless navigation coverage.
projects/igniteui-angular/grids/grid/src/grid.search.spec.ts Enables autoDetectChanges() for a scrolling + grouping search navigation test.
projects/igniteui-angular/grids/grid/src/grid.master-detail.spec.ts Enables autoDetectChanges() in an existing test and adds a zoneless master-detail navigation suite.
projects/igniteui-angular/grids/grid/src/grid.groupby.spec.ts Adds a zoneless grouped virtualization regression test (horizontal state restore with cached views).
projects/igniteui-angular/grids/grid/src/grid.component.spec.ts Adds zoneless rendering regressions for last-row visibility, aria-colcount stability, and horizontal virtualization chunk-load.
projects/igniteui-angular/grids/grid/src/grid-mrl-keyboard-nav.spec.ts Enables autoDetectChanges() in MRL keyboard navigation scrolling tests.
projects/igniteui-angular/grids/grid/src/grid-keyBoardNav.spec.ts Enables autoDetectChanges() in a keyboard navigation virtualization test.
projects/igniteui-angular/grids/grid/src/grid-keyBoardNav-headers.spec.ts Enables autoDetectChanges() in a scroll/focus test and converts one spec from fakeAsync to async timing.
projects/igniteui-angular/grids/grid/src/grid-filtering-ui.spec.ts Updates filter-chip interactions to use UI helper/click targets and tweaks column resize coordinates.
projects/igniteui-angular/grids/grid/src/grid-cell-selection.spec.ts Improves stability of an existing test and adds a zoneless keyboard selection regression.
projects/igniteui-angular/grids/grid/src/column.spec.ts Adds zoneless autosize regression for fit-content widths after data changes.
projects/igniteui-angular/grids/grid/src/column-group.spec.ts Makes a width assertion tolerant to sub-pixel rounding and moves the test to async timing.

@@ -1,4 +1,4 @@
import { Component, ViewChild, TemplateRef, QueryList } from '@angular/core';
import { Component, ViewChild, TemplateRef, QueryList, ChangeDetectionStrategy, provideZonelessChangeDetection } from '@angular/core';
@@ -1,7 +1,8 @@
import { Component, ViewChild, OnInit, DebugElement, QueryList, TemplateRef, ViewChildren } from '@angular/core';
import { Component, ViewChild, OnInit, DebugElement, QueryList, TemplateRef, ViewChildren, ChangeDetectionStrategy, provideZonelessChangeDetection } from '@angular/core';
@@ -1,6 +1,6 @@
import { AfterViewInit, ChangeDetectorRef, Component, Injectable, OnInit, ViewChild, TemplateRef, inject } from '@angular/core';
import { AfterViewInit, ChangeDetectorRef, Component, Injectable, OnInit, ViewChild, TemplateRef, inject, ChangeDetectionStrategy, provideZonelessChangeDetection } from '@angular/core';
@@ -1,4 +1,4 @@
import { Component, DebugElement, TemplateRef, ViewChild } from '@angular/core';
import { Component, DebugElement, TemplateRef, ViewChild, ChangeDetectionStrategy, provideZonelessChangeDetection } from '@angular/core';
import { TestBed, waitForAsync } from '@angular/core/testing';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { Component, ViewChild, DebugElement} from '@angular/core';
import { Component, ViewChild, DebugElement, ChangeDetectionStrategy, provideZonelessChangeDetection } from '@angular/core';
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants