Anz*_*haN 6 filetree angular angular-tree-component
我想在“角材料平面树”上显示“父级子级”图形表示。
这是设计:
这是我到目前为止所做的演示。
第一个解决方案
我对引用节点索引的每个可见节点进行了递归调用 treeControl.dataNodes.indexOf(node)
这是递归函数:
recNode(arr:any[], data:any[], index:number, maxIndex:number):any[]{
if (arr === undefined)
arr = [];
for (let i = 0; i < data.length; i++){
index++
if (index === maxIndex)
return ([true, index, arr]);
if (data[i].children.length){
let res = this.recNode(arr, data[i].children, index, maxIndex)
index = res[1];
if (res[0] === true)
{
arr.splice(0, 0, (i !== (data.length - 1)))
return ([true, index, arr]);
}
}
}
return ([false, index, arr]);
}
Run Code Online (Sandbox Code Playgroud)
这true false将为您返回一组值[ngClass]
然后在 html 中我这样调用该函数
<li *ngFor="let r of recNode(undefined, dataSource.data, -1, treeControl.dataNodes.indexOf(node))[2]; [ngClass]="{'node-arrow': r, 'node-arrow-empty': !r}" ></li>
Run Code Online (Sandbox Code Playgroud)
最后我在 css 中创建了另一个类,称为node-arrow-empty无边框
.node-arrow-nox {
position: relative;
// min-width: 48px;
// min-height: 48px;
.node-arrow {
position: relative;
min-width: 48px;
min-height: 48px;
&:before {
content: "";
position: absolute;
top: -20px;
left: 20px;
border-left: 1px solid $copounsCount;
bottom: 0;
}
}
.node-arrow-empty {
position: relative;
min-width: 48px;
min-height: 48px;
&:before {
content: "";
position: absolute;
top: -20px;
left: 20px;
bottom: 0;
}
}
}
Run Code Online (Sandbox Code Playgroud)
取决于数组中的值是true或false它在两个类之间的 html 中切换。
第二个解决方案
另一种解决方案是通过添加例如一个isLast:boolean属性来跟踪数组中的最后一个元素。当然,如果您正在处理的数据是动态的,您需要找到一种动态更改该值的方法。
一旦isLast填满你犯了一个递归调用,将查找以前的兄弟用current node level - 1。话虽如此,您将检查两件事。第一件事是,节点类包含n-last(这是我给 Html 表示父数组的最后一个元素的类名),第二件事是检索 class n-{{node-level}}。
通过递归(如果你不想,你可以创建一个非递归方法)检索previousElementSibling具有 classn-3或n-2...n-0的元素,你可以检查每个元素是否包含一个n-last类。您将trueor推false入一个数组,就像第一个解决方案在 classnode-arrow和之间切换一样node-arrow-empty。
这是递归函数
dummy(el:any, arr:any[], level:number){
let classes = el.className;
if (arr === undefined)
arr = [];
else{
arr.splice(0, 0, classes.includes('n-last'));
}
let np = /(?!n-)\d+/g;
let m = classes.match(np);
let nLevel = parseInt(m[0]);
nLevel--
if (nLevel < 0)
return (arr)
while (parseInt(el.className.match(np)[0]) !== nLevel){
el = el.previousElementSibling
}
arr = this.dummy(el, arr, nLevel)
return (arr)
}
Run Code Online (Sandbox Code Playgroud)
HTML(这里只有父节点,但对于子节点也是一样)
<mat-tree-node #refP class="parent-node {{'n-' + node.level}} " *matTreeNodeDef="let node; when: grpNode;" matTreeNodePadding matTreeNodePaddingIndent="0" cdkDrag [cdkDragData]="node" [ngClass]="{'no-child': !node.children.length, 'n-last': node.isLast}">
<span class="node-arrow-nox d-flex">
<li [ngClass]="{'node-arrow': !r , 'node-arrow-empty': r}" *ngFor="let r of dummy(refP, undefined, node.level)"></li>
</span>
<button class="node-toggle" mat-icon-button matTreeNodeToggle [attr.aria-label]="'toggle ' + node.filename" [disabled]="!node.children.length">
<mat-icon class="mat-icon-rtl-mirror toggle-arrow">
{{treeControl.isExpanded(node) ? 'play_arrow' : 'play_arrow'}}
</mat-icon>
</button>
<div class="node-icon icon-h-arw"></div>
<div class="node-name">{{node.isLast}}-{{node.accntCode}} <span>: :</span> {{node.name}} </div>
</mat-tree-node>
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,我正在将元素传递给带有名为的模板变量的虚拟功能 #refP
这是PARENTNODE和CHILDNODE声明:
export class PARENTNODE {
id: string;
isLast: boolean;
...
actAsSupplier: boolean;
}
/* Flat node with expandable and level information */
export class CHILDNODE {
constructor(
public id: string,
public isLast: boolean,
...
public actAsSupplier: boolean,
){}
}
Run Code Online (Sandbox Code Playgroud)
第三个解决方案
我不会编码,但我会尝试解释它。
这有点类似于以前的解决方案,除了您可以在树更改(交换、删除、添加)数据时进行解析并添加一个属性,例如divType填充true或false并在您的 html 中调用它
<li *ngFor="let r of node.divType" [ngClass]="{'node-arrow': r, 'node-arrow-empty': !r}" ></li>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
220 次 |
| 最近记录: |