/** * @license * Copyright Google LLC All Rights Reserved. * * 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 {ChangeDetectorRef, ChangeDetectionStrategy, Component} from '@angular/core'; import {SelectionModel} from '@angular/cdk/collections'; import {NestedTreeControl} from '@angular/cdk/tree'; import {Observable} from 'rxjs'; import {ChecklistDatabase, TodoItemNode} from './checklist-database'; /** * Checklist demo with nested tree */ @Component({ moduleId: module.id, selector: 'checklist-nested-tree-demo', templateUrl: 'checklist-nested-tree-demo.html', styleUrls: ['checklist-tree-demo.css'], providers: [ChecklistDatabase], changeDetection: ChangeDetectionStrategy.OnPush, }) export class ChecklistNestedTreeDemo { treeControl: NestedTreeControl; dataSource: TodoItemNode[]; /** The selection for checklist */ checklistSelection = new SelectionModel(true /* multiple */); constructor(private _database: ChecklistDatabase, private _changeDetectorRef: ChangeDetectorRef) { this.treeControl = new NestedTreeControl(this.getChildren); this.dataSource = _database.data; } getChildren = (node: TodoItemNode): Observable => node.children; hasNoContent = (_nodeData: TodoItemNode) => { return _nodeData.item === ''; }; /** Whether all the descendants of the node are selected */ descendantsAllSelected(node: TodoItemNode): boolean { const descendants = this.treeControl.getDescendants(node); if (!descendants.length) { return this.checklistSelection.isSelected(node); } const selected = this.checklistSelection.isSelected(node); const allSelected = descendants.every(child => this.checklistSelection.isSelected(child)); if (!selected && allSelected) { this.checklistSelection.select(node); this._changeDetectorRef.markForCheck(); } return allSelected; } /** Whether part of the descendants are selected */ descendantsPartiallySelected(node: TodoItemNode): boolean { const descendants = this.treeControl.getDescendants(node); if (!descendants.length) { return false; } const result = descendants.some(child => this.checklistSelection.isSelected(child)); return result && !this.descendantsAllSelected(node); } /** Toggle the to-do item selection. Select/deselect all the descendants node */ todoItemSelectionToggle(node: TodoItemNode): void { this.checklistSelection.toggle(node); const descendants = this.treeControl.getDescendants(node); this.checklistSelection.isSelected(node) ? this.checklistSelection.select(...descendants, node) : this.checklistSelection.deselect(...descendants, node); this._changeDetectorRef.markForCheck(); } /** Select the category so we can insert the new item. */ addNewItem(node: TodoItemNode) { this._database.insertItem(node, ''); this.treeControl.expand(node); } /** Save the node to database */ saveNode(node: TodoItemNode, itemValue: string) { this._database.updateItem(node, itemValue); } }