ну я создаю сервис с двумя функциями
getRootNodes(){}
и
getChildren(node:any){}
getRootNodes, возвращает первый уровень root.
getChildren (узлов: любой), вернуть «потомков». Но я не только возвращаю массив строк, но и возвращаю массив объектов с свойством isExpandable. Для материала-дерева необходимо знать, когда у детей есть дети
Следующим изменением является использование нашего сервиса в DinamicDataSource. Наш toggleNode должен использовать сервис. Если! extends - это код, который был в setTimeOut, ну, конечно, нам не нужен setTimeOut.
Если раскрыть = true, мы вызываем сервис и подписываемся на данные. В подписку код под setTimeOut.
Обратите внимание, что в обоих случаях нам нужно вызвать this.dataChange.next (this.data)
toggleNode(node: DynamicFlatNode, expand: boolean) {
const index = this.data.indexOf(node);
if (!expand)
{
let count = 0;
for (let i = index + 1; i < this.data.length
&& this.data[i].level > node.level; i++, count++) {}
this.data.splice(index + 1, count);
this.dataChange.next(this.data);
}
else
{
node.isLoading = true;
this.dataService.getChildren(node.item).subscribe(children=>{
if (!children || index < 0) { // If no children, or cannot find the node, no op
node.isLoading = false;
return;
}
if (expand) {
const nodes = children.map(obj =>
new DynamicFlatNode(obj.name, node.level + 1, obj.isExpandable));
this.data.splice(index + 1, 0, ...nodes);
}
node.isLoading = false;
// notify the change
this.dataChange.next(this.data);
})
}
}
Последнее изменение - это передача ngOnInit функций конструктора в TreeDynamicExample
ngOnInit()
{
this.treeControl = new FlatTreeControl<DynamicFlatNode>(this.getLevel, this.isExpandable);
this.dataSource = new DynamicDataSource(this.treeControl, this.dataService);
this.dataService.getRootNodes().subscribe(res=>{
this.dataSource.data = res.map(name => new DynamicFlatNode(name, 0, true));
})
}
Обратите внимание, что прежде чем сравнивать this.dataSourceData с DynamicFlatNode, нам нужно получить данные и сделать их в подписке
Обновление : демистификация источника DinamicData.
Ну, чтобы понять древовидную динамику, мы можем взглянуть на то, что является «данными» в источнике DynamicData. Эти данные это всего лишь массив объектов со свойствами: item, level, расширяемый и загружаемый. Итак, это выглядит как
[
{item: "Fruits",level:0,expandable:true,isLoading:false},
{item: "Apple",level:1,expandable:true,isLoading:false},
{item: "Orange",level:1,expandable:false,isLoading:false},
{item: "Bannana",level:1,expandable:false,isLoading:false},
{item: "Vegetables",level:0,expandable:true,isLoading:false}
]
Да, это просто массив. Но это упорядоченный массив. Таким образом, мы можем создать функцию addNode в нашем DinamicDataSource, например
addSubNode(index:number,name:string,isExpandable:boolean)
{
const node=this.data[index];
const dfn={item: name,
level:node.level+1,
expandable:isExpandable,
isLoading:false}
this.data.splice(index + 1, 0, ...[dfn]);
this.dataChange.next(this.data);
}
addNode(index:number,name:string,isExpandable:boolean)
{
const node=this.data[index];
const dfn={item: name,
level:node.level,
expandable:isExpandable,
isLoading:false}
this.data.splice(index + 1, 0, ...[dfn]);
this.dataChange.next(this.data);
}
changeNode(index:number,name:string)
{
this.data[index].item=name;
}
Обратите внимание, что после изменения массива с добавлением узла / подузла нам нужно вызвать this.dataChange.next (this.data), потому что сплайс изменяет «содержимое» массива, но не сам массив. Мы также можем сделать некоторые "bizarro" как
this.data=[...this.data]
но ребята из Angular Material облегчают нам жизнь, и мы можем использовать .next (это причина, потому что данные на самом деле не массив, а значение BehaviorSubject)
Я надеюсь, что это восклицание уберет "магию" из динамического дерева. Я разветвлял стек , чтобы добавить в дерево простые кнопки, чтобы добавить узел, добавить подузел и изменить узел