Skip to content

Commit

Permalink
fix(tree): not picking up indirect descendant node definitions (#17522)
Browse files Browse the repository at this point in the history
Fixes the CDK tree not picking up definitions that aren't direct descendants.
Also fixes some tests that won't fail if the tree doesn't render anything.
  • Loading branch information
crisbeto authored and mmalerba committed Oct 30, 2019
1 parent aadfcb5 commit 7f1c2ca
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 14 deletions.
49 changes: 36 additions & 13 deletions src/cdk/tree/tree.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,9 @@ describe('CdkTree', () => {
it('with the right accessibility roles', () => {
expect(treeElement.getAttribute('role')).toBe('tree');

getNodes(treeElement).forEach(node => {
expect(node.getAttribute('role')).toBe('treeitem');
});
expect(getNodes(treeElement).every(node => {
return node.getAttribute('role') === 'treeitem';
})).toBe(true);
});

it('with the right data', () => {
Expand Down Expand Up @@ -469,6 +469,15 @@ describe('CdkTree', () => {
expect(changedNodes[2].getAttribute('initialIndex')).toBe(null);
});
});

it('should pick up indirect descendant node definitions', () => {
configureCdkTreeTestingModule([SimpleCdkTreeAppWithIndirectNodes]);
const fixture = TestBed.createComponent(SimpleCdkTreeAppWithIndirectNodes);
fixture.detectChanges();
treeElement = fixture.nativeElement.querySelector('cdk-tree');

expect(getNodes(treeElement).length).toBe(3);
});
});

describe('nested tree', () => {
Expand Down Expand Up @@ -502,9 +511,9 @@ describe('CdkTree', () => {
it('with the right accessibility roles', () => {
expect(treeElement.getAttribute('role')).toBe('tree');

getNodes(treeElement).forEach(node => {
expect(node.getAttribute('role')).toBe('treeitem');
});
expect(getNodes(treeElement).every(node => {
return node.getAttribute('role') === 'treeitem';
})).toBe(true);
});

it('with the right data', () => {
Expand Down Expand Up @@ -827,9 +836,9 @@ describe('CdkTree', () => {
getNodes(initialNodes[0]).forEach((node: Element, index: number) => {
node.setAttribute('initialIndex', `c${index}`);
});
getNodes(initialNodes[0]).forEach((node, index) => {
expect(node.getAttribute('initialIndex')).toBe(`c${index}`);
});
expect(getNodes(initialNodes[0]).every((node, index) => {
return node.getAttribute('initialIndex') === `c${index}`;
})).toBe(true);
}

function mutateChildren(parent: TestData) {
Expand Down Expand Up @@ -965,10 +974,8 @@ describe('CdkTree', () => {

const depthElements = Array.from(treeElement.querySelectorAll('.tree-test-level')!);
const expectedLevels = ['0', '0', '1', '2', '0'];
depthElements.forEach((element, index) => {
const actualLevel = element.textContent!.trim();
expect(actualLevel).toBe(expectedLevels[index]);
});
const actualLevels = depthElements.map(element => element.textContent!.trim());
expect(actualLevels).toEqual(expectedLevels);
expect(depthElements.length).toBe(5);
});
});
Expand Down Expand Up @@ -1158,6 +1165,22 @@ class SimpleCdkTreeApp {
@ViewChildren(CdkTreeNodePadding) paddingNodes: QueryList<CdkTreeNodePadding<TestData>>;
}

@Component({
template: `
<cdk-tree [dataSource]="dataSource" [treeControl]="treeControl">
<ng-container [ngSwitch]="true">
<cdk-tree-node *cdkTreeNodeDef="let node" class="customNodeClass"
cdkTreeNodePadding [cdkTreeNodePaddingIndent]="indent"
cdkTreeNodeToggle>
{{node.pizzaTopping}} - {{node.pizzaCheese}} + {{node.pizzaBase}}
</cdk-tree-node>
</ng-container>
</cdk-tree>
`
})
class SimpleCdkTreeAppWithIndirectNodes extends SimpleCdkTreeApp {
}

@Component({
template: `
<cdk-tree [dataSource]="dataSource" [treeControl]="treeControl">
Expand Down
6 changes: 5 additions & 1 deletion src/cdk/tree/tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,11 @@ export class CdkTree<T> implements AfterContentChecked, CollectionViewer, OnDest
@ViewChild(CdkTreeNodeOutlet, {static: true}) _nodeOutlet: CdkTreeNodeOutlet;

/** The tree node template for the tree */
@ContentChildren(CdkTreeNodeDef) _nodeDefs: QueryList<CdkTreeNodeDef<T>>;
@ContentChildren(CdkTreeNodeDef, {
// We need to use `descendants: true`, because Ivy will no longer match
// indirect descendants if it's left as false.
descendants: true
}) _nodeDefs: QueryList<CdkTreeNodeDef<T>>;

// TODO(tinayuangao): Setup a listener for scrolling, emit the calculated view to viewChange.
// Remove the MAX_VALUE in viewChange
Expand Down

0 comments on commit 7f1c2ca

Please sign in to comment.