Fix(tree):allow NestedTreeControl to have null or undefined child (#14601)

This commit is contained in:
vivian-hu
2019-01-03 13:56:35 -08:00
committed by mmalerba
parent fe3ede46d8
commit ebdc873e98
5 changed files with 50 additions and 7 deletions
+1 -1
View File
@@ -34,7 +34,7 @@ export abstract class BaseTreeControl<T> implements TreeControl<T> {
isExpandable: (dataNode: T) => boolean;
/** Gets a stream that emits whenever the given data node's children change. */
getChildren: (dataNode: T) => (Observable<T[]> | T[]);
getChildren: (dataNode: T) => (Observable<T[]> | T[] | undefined | null);
/** Toggles one single data node's expanded/collapsed state. */
toggle(dataNode: T): void {
+1 -1
View File
@@ -13,7 +13,7 @@ import {BaseTreeControl} from './base-tree-control';
export class NestedTreeControl<T> extends BaseTreeControl<T> {
/** Construct with nested tree function getChildren. */
constructor(public getChildren: (dataNode: T) => (Observable<T[]> | T[])) {
constructor(public getChildren: (dataNode: T) => (Observable<T[]> | T[] | undefined | null)) {
super();
}
+1 -1
View File
@@ -60,5 +60,5 @@ export interface TreeControl<T> {
readonly isExpandable: (dataNode: T) => boolean;
/** Gets a stream that emits whenever the given data node's children change. */
readonly getChildren: (dataNode: T) => Observable<T[]> | T[];
readonly getChildren: (dataNode: T) => Observable<T[]> | T[] | undefined | null;
}
+43
View File
@@ -237,6 +237,26 @@ describe('MatTree', () => {
});
});
describe('nested tree with undefined or null children', () => {
describe('should initialize', () => {
let fixture: ComponentFixture<MatNestedTreeWithNullOrUndefinedChild >;
beforeEach(() => {
configureMatTreeTestingModule([MatNestedTreeWithNullOrUndefinedChild]);
fixture = TestBed.createComponent(MatNestedTreeWithNullOrUndefinedChild);
treeElement = fixture.nativeElement.querySelector('mat-tree');
fixture.detectChanges();
});
it('with rendered dataNodes', () => {
const nodes = getNodes(treeElement);
expect(nodes).toBeDefined('Expect nodes to be defined');
expect(nodes[0].classList).toContain('customNodeClass');
});
});
});
describe('nested tree', () => {
describe('should initialize', () => {
let fixture: ComponentFixture<NestedMatTreeApp>;
@@ -710,6 +730,29 @@ class MatTreeWithNullOrUndefinedChild {
hasChild = (_: number, node: ExampleFlatNode) => node.expandable;
}
@Component({
template: `
<mat-tree [dataSource]="dataSource" [treeControl]="treeControl">
<mat-nested-tree-node *matTreeNodeDef="let node" class="customNodeClass">
{{node.name}}
<ng-template matTreeNodeOutlet></ng-template>
</mat-nested-tree-node>
</mat-tree>
`
})
class MatNestedTreeWithNullOrUndefinedChild {
treeControl: NestedTreeControl<FoodNode>;
dataSource: MatTreeNestedDataSource<FoodNode>;
constructor() {
this.treeControl = new NestedTreeControl<FoodNode>(this.getChildren);
this.dataSource = new MatTreeNestedDataSource();
this.dataSource.data = TREE_DATA;
}
private getChildren = (node: FoodNode) => node.children;
}
@Component({
template: `
<mat-tree [dataSource]="dataSource" [treeControl]="treeControl">
+4 -4
View File
@@ -1,7 +1,7 @@
export declare abstract class BaseTreeControl<T> implements TreeControl<T> {
dataNodes: T[];
expansionModel: SelectionModel<T>;
getChildren: (dataNode: T) => (Observable<T[]> | T[]);
getChildren: (dataNode: T) => (Observable<T[]> | T[] | undefined | null);
getLevel: (dataNode: T) => number;
isExpandable: (dataNode: T) => boolean;
collapse(dataNode: T): void;
@@ -127,8 +127,8 @@ export declare function getTreeMultipleDefaultNodeDefsError(): Error;
export declare function getTreeNoValidDataSourceError(): Error;
export declare class NestedTreeControl<T> extends BaseTreeControl<T> {
getChildren: (dataNode: T) => (Observable<T[]> | T[]);
constructor(getChildren: (dataNode: T) => (Observable<T[]> | T[]));
getChildren: (dataNode: T) => (Observable<T[]> | T[] | undefined | null);
constructor(getChildren: (dataNode: T) => (Observable<T[]> | T[] | undefined | null));
protected _getDescendants(descendants: T[], dataNode: T): void;
expandAll(): void;
getDescendants(dataNode: T): T[];
@@ -137,7 +137,7 @@ export declare class NestedTreeControl<T> extends BaseTreeControl<T> {
export interface TreeControl<T> {
dataNodes: T[];
expansionModel: SelectionModel<T>;
readonly getChildren: (dataNode: T) => Observable<T[]> | T[];
readonly getChildren: (dataNode: T) => Observable<T[]> | T[] | undefined | null;
readonly getLevel: (dataNode: T) => number;
readonly isExpandable: (dataNode: T) => boolean;
collapse(dataNode: T): void;