Skip to content

Commit 4166d16

Browse files
jelbournjosephperrott
authored andcommitted
fix(tree): define CdkTree before CdkTreeNode to prevent errors in JIT (#11870)
1 parent 9a85b9b commit 4166d16

File tree

1 file changed

+76
-75
lines changed

1 file changed

+76
-75
lines changed

src/cdk/tree/tree.ts

Lines changed: 76 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -40,81 +40,6 @@ import {
4040
getTreeNoValidDataSourceError
4141
} from './tree-errors';
4242

43-
/**
44-
* Tree node for CdkTree. It contains the data in the tree node.
45-
*/
46-
@Directive({
47-
selector: 'cdk-tree-node',
48-
exportAs: 'cdkTreeNode',
49-
host: {
50-
'[attr.aria-expanded]': 'isExpanded',
51-
'[attr.aria-level]': 'role === "treeitem" ? level : null',
52-
'[attr.role]': 'role',
53-
'class': 'cdk-tree-node',
54-
},
55-
})
56-
export class CdkTreeNode<T> implements FocusableOption, OnDestroy {
57-
/**
58-
* The most recently created `CdkTreeNode`. We save it in static variable so we can retrieve it
59-
* in `CdkTree` and set the data to it.
60-
*/
61-
static mostRecentTreeNode: CdkTreeNode<{}> | null = null;
62-
63-
/** Subject that emits when the component has been destroyed. */
64-
protected _destroyed = new Subject<void>();
65-
66-
/** The tree node's data. */
67-
get data(): T { return this._data; }
68-
set data(value: T) {
69-
this._data = value;
70-
this._setRoleFromData();
71-
}
72-
protected _data: T;
73-
74-
get isExpanded(): boolean {
75-
return this._tree.treeControl.isExpanded(this._data);
76-
}
77-
78-
get level(): number {
79-
return this._tree.treeControl.getLevel ? this._tree.treeControl.getLevel(this._data) : 0;
80-
}
81-
82-
/**
83-
* The role of the node should be 'group' if it's an internal node,
84-
* and 'treeitem' if it's a leaf node.
85-
*/
86-
@Input() role: 'treeitem' | 'group' = 'treeitem';
87-
88-
constructor(protected _elementRef: ElementRef,
89-
protected _tree: CdkTree<T>) {
90-
CdkTreeNode.mostRecentTreeNode = this as CdkTreeNode<T>;
91-
}
92-
93-
ngOnDestroy() {
94-
this._destroyed.next();
95-
this._destroyed.complete();
96-
}
97-
98-
/** Focuses the menu item. Implements for FocusableOption. */
99-
focus(): void {
100-
this._elementRef.nativeElement.focus();
101-
}
102-
103-
private _setRoleFromData(): void {
104-
if (this._tree.treeControl.isExpandable) {
105-
this.role = this._tree.treeControl.isExpandable(this._data) ? 'group' : 'treeitem';
106-
} else {
107-
if (!this._tree.treeControl.getChildren) {
108-
throw getTreeControlFunctionsMissingError();
109-
}
110-
this._tree.treeControl.getChildren(this._data).pipe(takeUntil(this._destroyed))
111-
.subscribe(children => {
112-
this.role = children && children.length ? 'group' : 'treeitem';
113-
});
114-
}
115-
}
116-
}
117-
11843

11944
/**
12045
* CDK tree component that connects with a data source to retrieve data of type `T` and renders
@@ -351,3 +276,79 @@ export class CdkTree<T>
351276
}
352277
}
353278
}
279+
280+
281+
/**
282+
* Tree node for CdkTree. It contains the data in the tree node.
283+
*/
284+
@Directive({
285+
selector: 'cdk-tree-node',
286+
exportAs: 'cdkTreeNode',
287+
host: {
288+
'[attr.aria-expanded]': 'isExpanded',
289+
'[attr.aria-level]': 'role === "treeitem" ? level : null',
290+
'[attr.role]': 'role',
291+
'class': 'cdk-tree-node',
292+
},
293+
})
294+
export class CdkTreeNode<T> implements FocusableOption, OnDestroy {
295+
/**
296+
* The most recently created `CdkTreeNode`. We save it in static variable so we can retrieve it
297+
* in `CdkTree` and set the data to it.
298+
*/
299+
static mostRecentTreeNode: CdkTreeNode<{}> | null = null;
300+
301+
/** Subject that emits when the component has been destroyed. */
302+
protected _destroyed = new Subject<void>();
303+
304+
/** The tree node's data. */
305+
get data(): T { return this._data; }
306+
set data(value: T) {
307+
this._data = value;
308+
this._setRoleFromData();
309+
}
310+
protected _data: T;
311+
312+
get isExpanded(): boolean {
313+
return this._tree.treeControl.isExpanded(this._data);
314+
}
315+
316+
get level(): number {
317+
return this._tree.treeControl.getLevel ? this._tree.treeControl.getLevel(this._data) : 0;
318+
}
319+
320+
/**
321+
* The role of the node should be 'group' if it's an internal node,
322+
* and 'treeitem' if it's a leaf node.
323+
*/
324+
@Input() role: 'treeitem' | 'group' = 'treeitem';
325+
326+
constructor(protected _elementRef: ElementRef,
327+
protected _tree: CdkTree<T>) {
328+
CdkTreeNode.mostRecentTreeNode = this as CdkTreeNode<T>;
329+
}
330+
331+
ngOnDestroy() {
332+
this._destroyed.next();
333+
this._destroyed.complete();
334+
}
335+
336+
/** Focuses the menu item. Implements for FocusableOption. */
337+
focus(): void {
338+
this._elementRef.nativeElement.focus();
339+
}
340+
341+
private _setRoleFromData(): void {
342+
if (this._tree.treeControl.isExpandable) {
343+
this.role = this._tree.treeControl.isExpandable(this._data) ? 'group' : 'treeitem';
344+
} else {
345+
if (!this._tree.treeControl.getChildren) {
346+
throw getTreeControlFunctionsMissingError();
347+
}
348+
this._tree.treeControl.getChildren(this._data).pipe(takeUntil(this._destroyed))
349+
.subscribe(children => {
350+
this.role = children && children.length ? 'group' : 'treeitem';
351+
});
352+
}
353+
}
354+
}

0 commit comments

Comments
 (0)