Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
7c4c7dc
feat(cdk/tree): add demos to the dev-app
BobobUnicorn Feb 17, 2023
7835cdb
feat(cdk/tree): add flat-node with levelAccessor example to the demo
BobobUnicorn Feb 17, 2023
25cde66
feat(cdk/tree): move new demos to cdk-tree-redesign dir
BobobUnicorn Feb 17, 2023
06d47b0
fix(cdk/tree): fix unused error
BobobUnicorn Feb 17, 2023
66185a3
feat(cdk/tree): move demos back to their own dirs
BobobUnicorn Feb 17, 2023
cb105ae
fix(cdk/tree): address review comments
BobobUnicorn Feb 17, 2023
df29768
feat(cdk/tree): use _getDirectChildren method in nested node
BobobUnicorn Feb 17, 2023
3bbe6dd
feat(cdk/tree): add cache of nodes to the tree
BobobUnicorn Feb 17, 2023
c1025ec
fix(cdk/tree): fix cherry-pick errors
BobobUnicorn Feb 17, 2023
0befab7
feat(cdk/tree): add translation layer for nested nodes using levelAcc…
BobobUnicorn Feb 17, 2023
3be6e7c
feat(cdk/tree): add example with nested nodes & level accessor
BobobUnicorn Feb 17, 2023
015aef9
feat(cdk/tree): fix examples
BobobUnicorn Feb 17, 2023
4d60467
feat(cdk/tree): add example with flat nodes & childrenAccessor
BobobUnicorn Feb 17, 2023
1bb07d1
feat(cdk/tree): flatten data that uses childrenAccessor
BobobUnicorn Feb 17, 2023
c00f697
fix(cdk/tree): fix padding not showing for `childrenAccessor` trees
BobobUnicorn Feb 17, 2023
fe30c2b
fix(cdk/tree): fix flat tree demo
BobobUnicorn Feb 17, 2023
46cb0a7
fix(cdk/tree): convert generator function to return a regular array i…
BobobUnicorn Feb 17, 2023
97ae28d
fix(cdk/tree): fix build error
BobobUnicorn Feb 17, 2023
1f056cc
feat(cdk/tree): update API goldens
BobobUnicorn Feb 17, 2023
dd5c4c2
fix(cdk/tree): fix some failing tests, one remaining
BobobUnicorn Feb 17, 2023
8c4132d
fix(cdk/tree): fix test errors and children conversion; also make `re…
BobobUnicorn Feb 17, 2023
94cd73b
fix(cdk/tree): update api goldens
BobobUnicorn Feb 17, 2023
bdbd7dd
fix(cdk/tree): fix lint errors
BobobUnicorn Feb 17, 2023
ba562c3
fix(cdk/tree): also update flat level accessor example
BobobUnicorn Mar 13, 2023
74ef3a5
fix(cdk/tree): update API goldens
BobobUnicorn Apr 11, 2023
841edb2
feat(cdk/tree): add a translation function to the tree to get children
BobobUnicorn Feb 17, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 8 additions & 19 deletions src/cdk/tree/nested-node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,10 @@ import {
OnInit,
QueryList,
} from '@angular/core';
import {isObservable} from 'rxjs';
import {takeUntil} from 'rxjs/operators';

import {CDK_TREE_NODE_OUTLET_NODE, CdkTreeNodeOutlet} from './outlet';
import {CdkTree, CdkTreeNode} from './tree';
import {getTreeControlFunctionsMissingError} from './tree-errors';

/**
* Nested node is a child of `<cdk-tree>`. It works with nested tree.
Expand Down Expand Up @@ -69,22 +67,13 @@ export class CdkNestedTreeNode<T, K = T>

ngAfterContentInit() {
this._dataDiffer = this._differs.find([]).create(this._tree.trackBy);
const childrenAccessor = this._tree._getChildrenAccessor();
if (!childrenAccessor && (typeof ngDevMode === 'undefined' || ngDevMode)) {
throw getTreeControlFunctionsMissingError();
} else if (childrenAccessor) {
const childrenNodes = childrenAccessor(this.data);
if (Array.isArray(childrenNodes)) {
this.updateChildrenNodes(childrenNodes as T[]);
} else if (isObservable(childrenNodes)) {
childrenNodes
.pipe(takeUntil(this._destroyed))
.subscribe(result => this.updateChildrenNodes(result));
}
this.nodeOutlet.changes
.pipe(takeUntil(this._destroyed))
.subscribe(() => this.updateChildrenNodes());
}
this._tree
._getDirectChildren(this.data)
.pipe(takeUntil(this._destroyed))
.subscribe(result => this.updateChildrenNodes(result));
this.nodeOutlet.changes
.pipe(takeUntil(this._destroyed))
.subscribe(() => this.updateChildrenNodes());
}

// This is a workaround for https://github.com/angular/angular/issues/23091
Expand All @@ -106,7 +95,7 @@ export class CdkNestedTreeNode<T, K = T>
}
if (outlet && this._children) {
const viewContainer = outlet.viewContainer;
this._tree.renderNodeChanges(this._children, this._dataDiffer, viewContainer, this._data);
this._tree._renderNodeChanges(this._children, this._dataDiffer, viewContainer, this._data);
} else {
// Reset the data differ if there's no children nodes displayed
this._dataDiffer.diff([]);
Expand Down
3 changes: 1 addition & 2 deletions src/cdk/tree/padding.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,7 @@ export class CdkTreeNodePadding<T, K = T> implements OnDestroy {

/** The padding indent value for the tree node. Returns a string with px numbers if not null. */
_paddingIndent(): string | null {
const nodeLevel =
(this._treeNode.data && this._tree._getLevelAccessor()?.(this._treeNode.data)) ?? null;
const nodeLevel = (this._treeNode.data && this._tree._getLevel(this._treeNode.data)) ?? null;
const level = this._level == null ? nodeLevel : this._level;
return typeof level === 'number' ? `${level * this._indent}${this.indentUnits}` : null;
}
Expand Down
6 changes: 3 additions & 3 deletions src/cdk/tree/tree-errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ export function getMultipleTreeControlsError() {
}

/**
* Returns an error to be thrown when tree control did not implement functions for flat/nested node.
* Returns an error to be thrown when the node type is not specified.
* @docs-private
*/
export function getTreeControlFunctionsMissingError() {
return Error(`Could not find functions for nested/flat tree in tree control.`);
export function getTreeControlNodeTypeUnspecifiedError() {
return Error(`The nodeType was not specified for the tree.`);
}
83 changes: 31 additions & 52 deletions src/cdk/tree/tree-redesign.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {ComponentFixture, TestBed, fakeAsync, flush} from '@angular/core/testing';
import {ComponentFixture, TestBed} from '@angular/core/testing';
import {
Component,
ErrorHandler,
Expand All @@ -24,7 +24,6 @@ import {map} from 'rxjs/operators';

import {CdkTreeModule, CdkTreeNodePadding} from './index';
import {CdkTree, CdkTreeNode} from './tree';
import {getTreeControlFunctionsMissingError} from './tree-errors';

/**
* This is a cloned version of `tree.spec.ts` that contains all the same tests,
Expand Down Expand Up @@ -1127,20 +1126,6 @@ describe('CdkTree redesign', () => {
expect(changedNodes[5].getAttribute('initialIndex')).toBe('2');
});
});

it('should throw an error when missing function in nested tree', fakeAsync(() => {
configureCdkTreeTestingModule([NestedCdkErrorTreeApp]);
expect(() => {
try {
TestBed.createComponent(NestedCdkErrorTreeApp).detectChanges();
flush();
} catch {
flush();
} finally {
flush();
}
}).toThrowError(getTreeControlFunctionsMissingError().message);
}));
});

describe('with depth', () => {
Expand Down Expand Up @@ -1356,7 +1341,8 @@ function expectNestedTreeToMatch(treeElement: Element, ...expectedTree: any[]) {

@Component({
template: `
<cdk-tree [dataSource]="dataSource" [levelAccessor]="getLevel">
<cdk-tree [dataSource]="dataSource" [levelAccessor]="getLevel"
nodeType="flat">
<cdk-tree-node *cdkTreeNodeDef="let node" class="customNodeClass"
cdkTreeNodePadding [cdkTreeNodePaddingIndent]="indent"
cdkTreeNodeToggle
Expand All @@ -1383,7 +1369,8 @@ class SimpleCdkTreeApp {

@Component({
template: `
<cdk-tree [dataSource]="dataSource" [levelAccessor]="getLevel">
<cdk-tree [dataSource]="dataSource" [levelAccessor]="getLevel"
nodeType="flat">
<ng-container [ngSwitch]="true">
<cdk-tree-node *cdkTreeNodeDef="let node" class="customNodeClass"
cdkTreeNodePadding [cdkTreeNodePaddingIndent]="indent"
Expand All @@ -1399,7 +1386,8 @@ class SimpleCdkTreeAppWithIndirectNodes extends SimpleCdkTreeApp {}

@Component({
template: `
<cdk-tree [dataSource]="dataSource" [childrenAccessor]="getChildren">
<cdk-tree [dataSource]="dataSource" [childrenAccessor]="getChildren"
nodeType="nested">
<cdk-nested-tree-node *cdkTreeNodeDef="let node" class="customNodeClass">
{{node.pizzaTopping}} - {{node.pizzaCheese}} + {{node.pizzaBase}}
<ng-template cdkTreeNodeOutlet></ng-template>
Expand All @@ -1417,7 +1405,8 @@ class NestedCdkTreeApp {

@Component({
template: `
<cdk-tree [dataSource]="dataSource" [childrenAccessor]="getChildren">
<cdk-tree [dataSource]="dataSource" [childrenAccessor]="getChildren"
nodeType="nested">
<cdk-nested-tree-node *cdkTreeNodeDef="let node" class="customNodeClass">
{{node.pizzaTopping}} - {{node.pizzaCheese}} + {{node.pizzaBase}}
<ng-template cdkTreeNodeOutlet></ng-template>
Expand Down Expand Up @@ -1445,7 +1434,8 @@ class StaticNestedCdkTreeApp {

@Component({
template: `
<cdk-tree [dataSource]="dataSource" [childrenAccessor]="getChildren">
<cdk-tree [dataSource]="dataSource" [childrenAccessor]="getChildren"
nodeType="nested">
<cdk-nested-tree-node *cdkTreeNodeDef="let node" class="customNodeClass">
{{node.pizzaTopping}} - {{node.pizzaCheese}} + {{node.pizzaBase}}
<ng-template cdkTreeNodeOutlet></ng-template>
Expand All @@ -1469,7 +1459,8 @@ class WhenNodeNestedCdkTreeApp {

@Component({
template: `
<cdk-tree [dataSource]="dataSource" [levelAccessor]="getLevel">
<cdk-tree [dataSource]="dataSource" [levelAccessor]="getLevel"
nodeType="flat">
<cdk-tree-node *cdkTreeNodeDef="let node" class="customNodeClass"
cdkTreeNodePadding
cdkTreeNodeToggle [cdkTreeNodeToggleRecursive]="toggleRecursively"
Expand All @@ -1492,7 +1483,8 @@ class CdkTreeAppWithToggle {

@Component({
template: `
<cdk-tree #tree [dataSource]="dataSource" [childrenAccessor]="getChildren">
<cdk-tree #tree [dataSource]="dataSource" [childrenAccessor]="getChildren"
nodeType="nested">
<cdk-nested-tree-node *cdkTreeNodeDef="let node" class="customNodeClass"
cdkTreeNodeToggle [cdkTreeNodeToggleRecursive]="toggleRecursively">
{{node.pizzaTopping}} - {{node.pizzaCheese}} + {{node.pizzaBase}}
Expand All @@ -1515,7 +1507,8 @@ class NestedCdkTreeAppWithToggle {

@Component({
template: `
<cdk-tree [dataSource]="dataSource" [levelAccessor]="getLevel">
<cdk-tree [dataSource]="dataSource" [levelAccessor]="getLevel"
nodeType="flat">
<cdk-tree-node *cdkTreeNodeDef="let node" class="customNodeClass"
cdkTreeNodePadding [cdkTreeNodePaddingIndent]="28"
cdkTreeNodeToggle
Expand Down Expand Up @@ -1543,7 +1536,8 @@ class WhenNodeCdkTreeApp {

@Component({
template: `
<cdk-tree [dataSource]="dataArray" [levelAccessor]="getLevel">
<cdk-tree [dataSource]="dataArray" [levelAccessor]="getLevel"
nodeType="flat">
<cdk-tree-node *cdkTreeNodeDef="let node"
cdkTreeNodePadding [cdkTreeNodePaddingIndent]="28"
cdkTreeNodeToggle
Expand All @@ -1568,7 +1562,8 @@ class ArrayDataSourceCdkTreeApp {

@Component({
template: `
<cdk-tree [dataSource]="dataObservable" [levelAccessor]="getLevel">
<cdk-tree [dataSource]="dataObservable" [levelAccessor]="getLevel"
nodeType="flat">
<cdk-tree-node *cdkTreeNodeDef="let node"
cdkTreeNodePadding [cdkTreeNodePaddingIndent]="28"
cdkTreeNodeToggle
Expand All @@ -1593,7 +1588,8 @@ class ObservableDataSourceCdkTreeApp {

@Component({
template: `
<cdk-tree [dataSource]="dataArray" [childrenAccessor]="getChildren">
<cdk-tree [dataSource]="dataArray" [childrenAccessor]="getChildren"
nodeType="nested">
<cdk-nested-tree-node *cdkTreeNodeDef="let node">
[{{node.pizzaTopping}}] - [{{node.pizzaCheese}}] + [{{node.pizzaBase}}]
<ng-template cdkTreeNodeOutlet></ng-template>
Expand All @@ -1615,7 +1611,8 @@ class ArrayDataSourceNestedCdkTreeApp {

@Component({
template: `
<cdk-tree [dataSource]="dataObservable" [childrenAccessor]="getChildren">
<cdk-tree [dataSource]="dataObservable" [childrenAccessor]="getChildren"
nodeType="nested">
<cdk-nested-tree-node *cdkTreeNodeDef="let node">
[{{node.pizzaTopping}}] - [{{node.pizzaCheese}}] + [{{node.pizzaBase}}]
<ng-template cdkTreeNodeOutlet></ng-template>
Expand All @@ -1637,28 +1634,8 @@ class ObservableDataSourceNestedCdkTreeApp {

@Component({
template: `
<cdk-tree [dataSource]="dataSource" [levelAccessor]="getLevel">
<cdk-nested-tree-node *cdkTreeNodeDef="let node" class="customNodeClass"
[isExpandable]="isExpandable(node)">
{{node.pizzaTopping}} - {{node.pizzaCheese}} + {{node.pizzaBase}}
<ng-template cdkTreeNodeOutlet></ng-template>
</cdk-nested-tree-node>
</cdk-tree>
`,
})
class NestedCdkErrorTreeApp {
getLevel = (node: TestData) => node.level;

isExpandable = (node: TestData) => node.children.length > 0;

dataSource: FakeDataSource | null = new FakeDataSource();

@ViewChild(CdkTree) tree: CdkTree<TestData>;
}

@Component({
template: `
<cdk-tree [dataSource]="dataArray" [childrenAccessor]="getChildren">
<cdk-tree [dataSource]="dataArray" [childrenAccessor]="getChildren"
nodeType="nested">
<cdk-nested-tree-node *cdkTreeNodeDef="let node; let level = level">
<span class="tree-test-level">{{level}}</span>
[{{node.pizzaTopping}}] - [{{node.pizzaCheese}}] + [{{node.pizzaBase}}]
Expand All @@ -1681,7 +1658,8 @@ class DepthNestedCdkTreeApp {

@Component({
template: `
<cdk-tree [dataSource]="dataSource" [levelAccessor]="getLevel" [trackBy]="trackByFn">
<cdk-tree [dataSource]="dataSource" [levelAccessor]="getLevel" [trackBy]="trackByFn"
nodeType="flat">
<cdk-tree-node *cdkTreeNodeDef="let node" class="customNodeClass" [isExpandable]="isExpandable(node)">
{{node.pizzaTopping}} - {{node.pizzaCheese}} + {{node.pizzaBase}}
</cdk-tree-node>
Expand Down Expand Up @@ -1712,7 +1690,8 @@ class CdkTreeAppWithTrackBy {

@Component({
template: `
<cdk-tree [dataSource]="dataArray" [childrenAccessor]="getChildren" [trackBy]="trackByFn">
<cdk-tree [dataSource]="dataArray" [childrenAccessor]="getChildren" [trackBy]="trackByFn"
nodeType="nested">
<cdk-nested-tree-node *cdkTreeNodeDef="let node">
[{{node.pizzaTopping}}] - [{{node.pizzaCheese}}] + [{{node.pizzaBase}}]
<ng-template cdkTreeNodeOutlet></ng-template>
Expand Down
39 changes: 1 addition & 38 deletions src/cdk/tree/tree.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {ComponentFixture, TestBed, fakeAsync, flush} from '@angular/core/testing';
import {ComponentFixture, TestBed} from '@angular/core/testing';
import {
Component,
ErrorHandler,
Expand All @@ -27,7 +27,6 @@ import {FlatTreeControl} from './control/flat-tree-control';
import {NestedTreeControl} from './control/nested-tree-control';
import {CdkTreeModule, CdkTreeNodePadding} from './index';
import {CdkTree, CdkTreeNode} from './tree';
import {getTreeControlFunctionsMissingError} from './tree-errors';

describe('CdkTree', () => {
/** Represents an indent for expectNestedTreeToMatch */
Expand Down Expand Up @@ -1126,20 +1125,6 @@ describe('CdkTree', () => {
expect(changedNodes[5].getAttribute('initialIndex')).toBe('2');
});
});

it('should throw an error when missing function in nested tree', fakeAsync(() => {
configureCdkTreeTestingModule([NestedCdkErrorTreeApp]);
expect(() => {
try {
TestBed.createComponent(NestedCdkErrorTreeApp).detectChanges();
flush();
} catch {
flush();
} finally {
flush();
}
}).toThrowError(getTreeControlFunctionsMissingError().message);
}));
});

describe('with depth', () => {
Expand Down Expand Up @@ -1633,28 +1618,6 @@ class ObservableDataSourceNestedCdkTreeApp {
@ViewChild(CdkTree) tree: CdkTree<TestData>;
}

@Component({
template: `
<cdk-tree [dataSource]="dataSource" [treeControl]="treeControl">
<cdk-nested-tree-node *cdkTreeNodeDef="let node" class="customNodeClass">
{{node.pizzaTopping}} - {{node.pizzaCheese}} + {{node.pizzaBase}}
<ng-template cdkTreeNodeOutlet></ng-template>
</cdk-nested-tree-node>
</cdk-tree>
`,
})
class NestedCdkErrorTreeApp {
getLevel = (node: TestData) => node.level;

isExpandable = (node: TestData) => node.children.length > 0;

treeControl: TreeControl<TestData> = new FlatTreeControl(this.getLevel, this.isExpandable);

dataSource: FakeDataSource | null = new FakeDataSource(this.treeControl);

@ViewChild(CdkTree) tree: CdkTree<TestData>;
}

@Component({
template: `
<cdk-tree [dataSource]="dataArray" [treeControl]="treeControl">
Expand Down
Loading