javascript - hur man skapar en kollapsbar/expanderbar/trädstruktur med kryssrutelista med hjälp av angular 6 & bootstrap 3.3.7


Jag försöker skapa en kollapsbar/trädstruktur med kryssrutor på både föräldra- och barnnoder. Jag har inte kunnat skapa den exakt. Jag kunde skapa ända fram till oordnad lista från JSON.

{
  "properties": {
    "host": {
      "fields": {
        "keyword": {
          "ignore_above": 256,
          "type": "keyword"
        }
      },
      "type": "text",
      "fielddata": true
    },
    "information": {
      "properties": {
        "filetype": {
          "fields": {
            "keyword": {
              "ignore_above": 256,
              "type": "keyword"
            }
          },
          "type": "text",
          "fielddata": true
        },
        "author": {
          "fields": {
            "keyword": {
              "ignore_above": 256,
              "type": "keyword"
            }
          },
          "type": "text",
          "fielddata": true
        },
        "authorcountry": {
          "fields": {
            "keyword": {
              "ignore_above": 256,
              "type": "keyword"
            }
          },
          "type": "text",
          "fielddata": true
        }
      }
    },
    "url": {
      "fields": {
        "keyword": {
          "ignore_above": 256,
          "type": "keyword"
        }
      },
      "type": "text",
      "fielddata": true
    },
    "name": {
      "fields": {
        "keyword": {
          "ignore_above": 256,
          "type": "keyword"
        }
      },
      "type": "text",
      "fielddata": true
    },
    "instrument": {
      "properties": {
        "Style": {
          "fields": {
            "keyword": {
              "ignore_above": 256,
              "type": "keyword"
            }
          },
          "type": "text",
          "fielddata": true
        },
        "instrumentCode": {
          "type": "integer"
        },
        "instrumentName": {
          "type": "text"
        },
        "instrumentNumber": {
          "fields": {
            "keyword": {
              "ignore_above": 256,
              "type": "keyword"
            }
          },
          "type": "text",
          "fielddata": true
        }

      }
    }
  }
}

.html-kod

<button class="btn btn-primary" (click)="getData()">getData</button>


<h1>ul element</h1>

<hr>

 <ul class="list-group"   *ngFor="let x of inf | keyvalue">
    <li class="list-group-item">{{x.key}}</li>
    <ng-container *ngIf="x.value.hasOwnProperty('properties')">
      <ul *ngFor="let y of x.value.properties | keyvalue">
      <li>
        {{y.key}}
      </li>
      </ul>  
    </ng-container> 
  </ul>

utrullbar /trädstruktur.

Nedan är min Stackblitz-länk:

https://stackblitz.com/edit/angular-k5tdpe

Jag kan också prova plugins, men indataformatet för plugins var olika: angular2-tree-plugin och ng2-tree/ngx-tree, så några förslag...

Svar #1

lägg bara till en inmatningstypkontroll och använd [(ngModel)]

<ul class="list-group"   *ngFor="let x of inf | keyvalue">
    <li class="list-group-item">
     <!--add a input type checkbox and relation with x.check-->
     <input type="checkbox" [(ngModel)]="x.check">
     {{x.key}}</li>
    <!---change the *ngIf to add the x.check condition-->
    <ng-container *ngIf="x.check && x.value.hasOwnProperty('properties')">
      <ul *ngFor="let y of x.value.properties | keyvalue">
      <li>
        {{y.key}}
      </li>
      </ul>  
    </ng-container> 
  </ul>

Uppdaterad om du vill ha en "rekursiv komponent" är det enkelt. Jag har lagt till ett exempel, du kan se resultatet i stackblitz

I princip är en "rekursiv komponent" en komponent som i mallen har samma komponent. Vanligtvis använder vi en json-modell med egenskaperna children (ja, du kan omvandla din "komplexa" json till någon som har egenskaperna an children). Om du en gång skapar en jsondata med children, är din json som, t.ex. som

data = [{
    title: "uno", children: [
      { title: "uno-uno" }]
  },
  {
    title: "dos", children: [
      { title: "dos-uno",children: [
           { title: "dos-uno" }
           ]},
      { title: "dos-dos" }]
  }
  ]

Vi kan ha en app.component som

  <li *ngFor="let item of data">
     <app-li [title]="item.title" [children]="item.children"></app-li>
  </li>

Och vår app-li som

<li (click)="check=!check">
      <div [className]="children?check?'arrow-down':'arrow-up':'arrow-right'"></div>
      {{title}}
</li>
<ul *ngIf="children && check">
  <ng-container *ngFor="let item of children">
       <app-li [title]="item.title" [children]="item.children"></app-li>
  </ng-container>
</ul>

Se till att vi matar app-li med "barn"

OBS: Jag lägger till en <div> med className för att "simulera" trianglarna

Uppdaterad 2 Vi kan skicka själva objektet

Komponenten blir som

@Component({
  selector: 'app-li',
  template: `<li >
              <div (click)="check=!check" [className]="item.children?
                   check?'arrow-down':'arrow-up':'arrow-right'">
              </div>
              <input type="checkbox" [(ngModel)]="item.select" >
              <span (click)="check=!check">{{item.title}}</span>
              </li>
             <ul *ngIf="item.children && check">
             <ng-container *ngFor="let item of item.children">
               <app-li [item]="item" ></app-li>
               </ng-container>
             </ul>
  `,
    styleUrls: [ './hello.component.css' ]



})
export class HelloComponent  {
  @Input() item: any;
}

Och appen

<li *ngFor="let item of data">
     <app-li [item]="item" ></app-li>
</li>

Se stackblitz-fork

Relaterade artiklar