diff --git a/npm/ng-packs/packages/core/src/lib/directives/permission.directive.ts b/npm/ng-packs/packages/core/src/lib/directives/permission.directive.ts
index b12782288d..d9ad09c780 100644
--- a/npm/ng-packs/packages/core/src/lib/directives/permission.directive.ts
+++ b/npm/ng-packs/packages/core/src/lib/directives/permission.directive.ts
@@ -52,7 +52,9 @@ export class PermissionDirective implements OnDestroy, OnChanges, AfterViewInit
if (!this.rendered) {
this.cdrSubject.next();
} else {
- this.cdRef.detectChanges();
+ // Defer via queue — sync detectChanges during ApplicationRef.tick
+ // (e.g. post-login permission/config refresh) can contribute to NG0101.
+ this.queue.add(() => this.cdRef.detectChanges());
}
} else {
this.cdRef.markForCheck();
diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/breadcrumb/breadcrumb.component.html b/npm/ng-packs/packages/theme-shared/src/lib/components/breadcrumb/breadcrumb.component.html
index b23fdc598e..1eabd84821 100644
--- a/npm/ng-packs/packages/theme-shared/src/lib/components/breadcrumb/breadcrumb.component.html
+++ b/npm/ng-packs/packages/theme-shared/src/lib/components/breadcrumb/breadcrumb.component.html
@@ -1 +1 @@
-
+
diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/breadcrumb/breadcrumb.component.ts b/npm/ng-packs/packages/theme-shared/src/lib/components/breadcrumb/breadcrumb.component.ts
index b8a86342b1..884eb9db99 100644
--- a/npm/ng-packs/packages/theme-shared/src/lib/components/breadcrumb/breadcrumb.component.ts
+++ b/npm/ng-packs/packages/theme-shared/src/lib/components/breadcrumb/breadcrumb.component.ts
@@ -6,7 +6,7 @@ import {
SubscriptionService,
TreeNode,
} from '@abp/ng.core';
-import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit, inject } from '@angular/core';
+import { ChangeDetectionStrategy, Component, OnInit, inject, signal } from '@angular/core';
import { Router } from '@angular/router';
import { map, startWith } from 'rxjs/operators';
import { eThemeSharedRouteNames } from '../../enums/route-names';
@@ -20,14 +20,13 @@ import { BreadcrumbItemsComponent } from '../breadcrumb-items/breadcrumb-items.c
imports: [BreadcrumbItemsComponent],
})
export class BreadcrumbComponent implements OnInit {
- readonly cdRef = inject(ChangeDetectorRef);
private router = inject(Router);
private routes = inject(RoutesService);
private subscription = inject(SubscriptionService);
private routerEvents = inject(RouterEvents);
private routeCultureUrl = inject(RouteBasedCultureUrlService);
- segments: Partial[] = [];
+ readonly segments = signal[]>([]);
ngOnInit(): void {
this.subscription.addOne(
@@ -38,18 +37,18 @@ export class BreadcrumbComponent implements OnInit {
),
),
route => {
- this.segments = [];
+ const next: Partial[] = [];
if (route) {
let node = { parent: route } as TreeNode;
while (node.parent) {
node = node.parent;
const { parent, children, isLeaf, ...segment } = node;
- if (!isAdministration(segment)) this.segments.unshift(segment);
+ if (!isAdministration(segment)) next.unshift(segment);
}
-
- this.cdRef.detectChanges();
}
+
+ this.segments.set(next);
},
);
}
diff --git a/npm/ng-packs/packages/theme-shared/src/lib/services/toaster.service.ts b/npm/ng-packs/packages/theme-shared/src/lib/services/toaster.service.ts
index b6db6e7716..f1f3a5c114 100644
--- a/npm/ng-packs/packages/theme-shared/src/lib/services/toaster.service.ts
+++ b/npm/ng-packs/packages/theme-shared/src/lib/services/toaster.service.ts
@@ -1,4 +1,4 @@
-import { ApplicationRef, ComponentRef, inject, Injectable } from '@angular/core';
+import { ComponentRef, inject, Injectable } from '@angular/core';
import {
ContentProjectionService,
LocalizationParam,
@@ -12,7 +12,6 @@ import { Toaster } from '../models';
providedIn: 'root',
})
export class ToasterService implements ToasterContract {
- private readonly appRef = inject(ApplicationRef);
private readonly contentProjectionService = inject(ContentProjectionService);
private lastId = -1;
@@ -37,8 +36,9 @@ export class ToasterService implements ToasterContract {
}
this.containerComponentRef.instance.setToasts(this.toasts);
+ // Only refresh the projected toast host. Calling ApplicationRef.tick() here
+ // races with zone-driven CD and throws NG0101 (recursive tick).
this.containerComponentRef.changeDetectorRef.detectChanges();
- this.appRef.tick();
}
/**
diff --git a/npm/ng-packs/packages/theme-shared/src/lib/tests/breadcrumb.component.spec.ts b/npm/ng-packs/packages/theme-shared/src/lib/tests/breadcrumb.component.spec.ts
index 6ad217d3b8..ce1463e2cf 100644
--- a/npm/ng-packs/packages/theme-shared/src/lib/tests/breadcrumb.component.spec.ts
+++ b/npm/ng-packs/packages/theme-shared/src/lib/tests/breadcrumb.component.spec.ts
@@ -135,7 +135,7 @@ describe('BreadcrumbComponent', () => {
const breadcrumb = spectator.fixture.debugElement.query(By.directive(BreadcrumbComponent))
.componentInstance as BreadcrumbComponent;
- expect(breadcrumb.segments.map(segment => segment.path)).toEqual([
+ expect(breadcrumb.segments().map(segment => segment.path)).toEqual([
'/identity',
'/identity/users',
]);