diff --git a/devtools/projects/ng-devtools-backend/src/lib/directive-forest/render-tree.ts b/devtools/projects/ng-devtools-backend/src/lib/directive-forest/render-tree.ts
index 7fe9c8d574ad..fe8a092bcc20 100644
--- a/devtools/projects/ng-devtools-backend/src/lib/directive-forest/render-tree.ts
+++ b/devtools/projects/ng-devtools-backend/src/lib/directive-forest/render-tree.ts
@@ -11,7 +11,7 @@ import {
ɵDeferBlockData as DeferBlockData,
ɵHydratedNode as HydrationNode,
} from '@angular/core';
-import {CurrentDeferBlock, HydrationStatus} from '../../../../protocol';
+import {RenderedDeferBlock, HydrationStatus} from '../../../../protocol';
import {ComponentTreeNode} from '../interfaces';
import {ngDebugClient} from '../ng-debug-api/ng-debug-api';
@@ -126,14 +126,19 @@ function groupDeferChildrenIfNeeded(
getDirectiveMetadata?: FrameworkAgnosticGlobalUtils['getDirectiveMetadata'],
) {
const currentDeferBlock = deferBlocks.currentBlock;
- const isFirstDefferedChild = node === currentDeferBlock?.rootNodes[0];
- if (isFirstDefferedChild) {
+ const isFirstDeferredChild = node === currentDeferBlock?.rootNodes[0];
+ // Handles the case where the @defer is still unresolved but doesn't
+ // have a placeholder, for instance, by which children we mark
+ // the position of the block normally. In this case, we use the host.
+ const isHostNode = node === currentDeferBlock?.hostNode;
+
+ if (isFirstDeferredChild || isHostNode) {
deferBlocks.advance();
- // When encountering the first child of a defer block
- // We create a synthetic TreeNode reprensenting the defer block
+ // When encountering the first child of a defer block (or the host node),
+ // we create a synthetic TreeNode representing the defer block.
const childrenTree: ComponentTreeNode[] = [];
- currentDeferBlock.rootNodes.forEach((child) => {
+ for (const child of currentDeferBlock.rootNodes) {
extractViewTree(
child,
childrenTree,
@@ -143,7 +148,7 @@ function groupDeferChildrenIfNeeded(
getDirectives,
getDirectiveMetadata,
);
- });
+ }
const deferBlockTreeNode = {
children: childrenTree,
@@ -155,7 +160,7 @@ function groupDeferChildrenIfNeeded(
defer: {
id: `deferId-${rootId}-${deferBlocks.currentIndex}`,
state: currentDeferBlock.state,
- currentBlock: currentBlock(currentDeferBlock),
+ renderedBlock: getRenderedBlock(currentDeferBlock),
triggers: groupTriggers(currentDeferBlock.triggers),
blocks: {
hasErrorBlock: currentDeferBlock.hasErrorBlock,
@@ -213,12 +218,16 @@ function groupTriggers(triggers: string[]) {
return {defer, hydrate, prefetch};
}
-function currentBlock(deferBlock: DeferBlockData): CurrentDeferBlock | null {
+function getRenderedBlock(deferBlock: DeferBlockData): RenderedDeferBlock | null {
if (['placeholder', 'loading', 'error'].includes(deferBlock.state)) {
return deferBlock.state as 'placeholder' | 'loading' | 'error';
}
+ if (deferBlock.state === 'complete') {
+ return 'defer';
+ }
return null;
}
+
export class RTreeStrategy {
supports(): boolean {
return (['getDirectiveMetadata', 'getComponent'] as const).every(
@@ -253,7 +262,7 @@ class DeferBlocksIterator {
this.currentIndex++;
}
- get currentBlock() {
+ get currentBlock(): DeferBlockData | undefined {
return this.blocks[this.currentIndex];
}
}
diff --git a/devtools/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/directive-forest/tree-node/tree-node.component.html b/devtools/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/directive-forest/tree-node/tree-node.component.html
index ff1a7157b2fc..ea358b723923 100644
--- a/devtools/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/directive-forest/tree-node/tree-node.component.html
+++ b/devtools/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/directive-forest/tree-node/tree-node.component.html
@@ -29,18 +29,22 @@
@if (node().onPush) {
- OnPush
+ OnPush
}
@let defer = node().defer;
@if (!defer && (!hydration || hydration.status !== 'dehydrated')) {
- == $ng0
+ == $ng0
}
- @if (defer && defer.currentBlock) {
- (@{{ defer.currentBlock }})
+ @if (defer) {
+ @if (defer.renderedBlock && defer.renderedBlock !== 'defer') {
+ (@{{ defer.renderedBlock }})
+ } @else if (!defer.renderedBlock) {
+ (non-rendered)
+ }
}
@switch (hydration?.status) {
diff --git a/devtools/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/directive-forest/tree-node/tree-node.component.scss b/devtools/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/directive-forest/tree-node/tree-node.component.scss
index 4a6ae0191588..ae6ff1db2f56 100644
--- a/devtools/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/directive-forest/tree-node/tree-node.component.scss
+++ b/devtools/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/directive-forest/tree-node/tree-node.component.scss
@@ -99,8 +99,7 @@
display: none;
}
- .console-reference,
- .on-push {
+ .trait {
color: var(--color-tree-node-console-ref);
padding-left: 8px;
font-style: italic;
diff --git a/devtools/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/directive-forest/tree-node/tree-node.component.spec.ts b/devtools/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/directive-forest/tree-node/tree-node.component.spec.ts
index 544911630bdb..e251f766a201 100644
--- a/devtools/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/directive-forest/tree-node/tree-node.component.spec.ts
+++ b/devtools/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/directive-forest/tree-node/tree-node.component.spec.ts
@@ -97,9 +97,9 @@ describe('TreeNodeComponent', () => {
});
await fixture.whenStable();
- onPush = fixture.debugElement.query(By.css('.on-push'));
+ onPush = fixture.debugElement.query(By.css('.trait'));
- expect(onPush).toBeTruthy();
+ expect(onPush.nativeElement.textContent).toEqual('OnPush');
});
it('should handle selection', async () => {
diff --git a/devtools/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/property-tab/defer-view/defer-view.component.html b/devtools/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/property-tab/defer-view/defer-view.component.html
index 28d83da4696d..747d05bfccfa 100644
--- a/devtools/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/property-tab/defer-view/defer-view.component.html
+++ b/devtools/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/property-tab/defer-view/defer-view.component.html
@@ -1,30 +1,36 @@
-