Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
597 views
in Technique[技术] by (71.8m points)

html - Create tree view with horizontal and vertical lines showing the connectivity using css

I'm having the requirement where we need to show the nested elements to have horizontal and vertical line for folders and subfolder. i searched but unable to find anything relevant. See below picture for reference.

Sample Image

Can someone help me in this issue.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The first it's know how make it using .css. I find this beauty Minimalist Tree View In Pure CSS

Well, with this idea we can use Angular to generate a "recursive component". but first we must take account that we need use "attribute selector" to not generate the tag of the component. Don't worry, it's only use as selector some like

selector: '[recursive]'

So, instead of write some like

<recursive></recursive>

we can use some like

<ul recursive></ul>

Well, the component is like

<li *ngFor="let item of children">
    {{item.label}}
    <ul recursive *ngIf="item.children" 
        [children]="item.children" 
        [parent]="self" 
        [level]="level!=undefined?level+1:0">
    </ul>
</li>

@Component({
  selector: '[recursive]', //<--the the "selector"
  templateUrl:'./hello.component.html'
})    
export class HelloComponent  {
  @Input() level: number;
  @Input() label: string;
  @Input() children: any;
  @Input() parent: any;

  self=this;

}

Well, I add the properties "level" and "parent" that I don't use in the code but can be interesting if our component make "some-more" that show the tree.

And our app.component.html is some like

<ul class="tree" recursive [children]="data"></ul>

Be carefull. I need use ViewEncapsulation.None in the app.component to transport the .css

See that we give [children] the own data

where, e.g.

data = [{label: "Parent1", children: [
      { label: "Parent 1's only child"  }
  ]},
    {label:"Parent2"},
    {label:"Parent3", children: [
      { label: "1st Child of 3" ,children:[
         {label:"1st grandchild"},
         {label:"2nd grandchild"}
      ]},
      { label: "2nd Child of 3" },
      { label: "3rd Child of 3" }
      ]
   },
   {
    label: "Parent 4", children: [
      { label: "Parent 4's only child"  }
  ]}]

You can see in this stackblitz

Updated If we want add open/close capacity, it's easy adding a span and using [ngClass] for the three cases: doc, open and close, so our recursive.html becomes

<li *ngFor="let item of children">
    <span [ngClass]="!item.children?
         'doc':item.isOpen?'open':'close'" 
         (click)="item.isOpen=!item.isOpen"></span>
    {{item.label}}
    <ul recursive *ngIf="item.children && item.isOpen" 
        [children]="item.children" 
        [parent]="self" 
        [level]="level!=undefined?level+1:0">
    </ul>
</li>

I used a .css like

.doc,.open,.close
{
  display:inline-block;
  width:1rem;
  height:1rem;
  background-size: 1rem 1rem;
}
.doc
{
  background-image:url('...');
}
.open
{
  background-image:url('...');
}
.close
{
  background-image:url('...');
}

The updated stackblitz

Updated 2 I don't like so much use ViewEncapsulation.None, so we can make a work-around and our recursive component becomes like

<ul class="tree" *ngIf="level==undefined">
  <ng-container *ngTemplateOutlet="tree;context:{children:children}">
  </ng-container>
</ul>
<ng-container *ngIf="level!=undefined">
  <ng-container *ngTemplateOutlet="tree;context:{children:children}">
  </ng-container>
</ng-container>

<ng-template #tree let-children="children">
<li *ngFor="let item of children">
    <span [ngClass]="!item.children?'doc':item.isOpen?'open':'close'" (click)="item.isOpen=!item.isOpen"></span>{{item.label}}
    <ul recursive *ngIf="item.children && item.isOpen" 
        [children]="item.children" 
        [parent]="self" 
        [level]="level!=undefined?level+1:0">
            </ul>
</li>
</ng-template>

That's. The first use a <ul class="tree">...</ul>, the others not add the <ul>

Again, the final stackblitz


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...