如何使用 Angular 6 和 bootstrap 3.3.7 创建带有复选框列表的可折叠/可扩展/树结构

Posted

技术标签:

【中文标题】如何使用 Angular 6 和 bootstrap 3.3.7 创建带有复选框列表的可折叠/可扩展/树结构【英文标题】:how to create collapsible/expandable/ Tree structure with checkbox list using angular 6 & bootstrap 3.3.7 【发布时间】:2019-05-10 03:25:03 【问题描述】:

在这里,我正在尝试使用父子和子节点上的复选框的可折叠/树结构,但我无法准确地创建它,直到从 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代码

<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>

可折叠/树结构

下面是我的 stackblitz 链接

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

我也可以尝试插件,但插件的输入数据格式不同 angular2-tree plugin & ng2 -tree /ngx-tree 所以有什么建议

【问题讨论】:

虽然使用属性名称作为值可能看起来很简洁,但使用它们做任何事情变得更加困难。我建议您为树的每个节点考虑一个单一、一致的 javascript 结构。 name: "mynode", data: "whatever", children: [name: "mychild", data: "stuff",name: "mychild2",data: "Stuff2"] @James 我可以将我现有的数据转换为该格式吗?如果可以,您可以使用我现有的 json 数据创建一个示例。我还根据需要检查了 ng-tree 我的整个网站使用上述 json 格式的相同格式,所以只有为此我需要获取 diff 格式 【参考方案1】:

只需添加输入类型检查并使用 [(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>

更新 如果你想要一个“递归组件”很容易。我举个例子,你可以在stackblitz看到结果

基本上,“递归组件是模板中具有相同组件的组件。通常我们使用具有子属性的 json 模型(是的,您可以将“复杂”json 转换为具有子属性的某些组件)如果有一次你创建一个带有孩子的 jsondata,你的 json 就像,例如,像

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

我们可以有一个 app.component 像

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

和我们的 app-li 一样

<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>

看到我们用“children”喂给 app-li

注意:我添加了一个带有 className 的

来“模拟”三角形

更新 2 我们可以传递自己的项目本身t

组件变成像

@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;

还有应用程序

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

见stackblitz forked

【讨论】:

你能帮我解决堆栈闪电战的这些变化吗?我怎样才能获得点击功能? 只是替换代码,你可以在你的fork stackblitz中看到stackblitz.com/edit/angular-mpyve9?file=src/app/… 实际上这是我做的,但内部子代也必须与父代一起选择,我们可能有 n 个子代,无论我们选择哪个值以及必须选择特定子代的父代,以及相似父母假设如果信息父母没有孩子,那么如果“信息”有孩子,那么我必须将“信息”作为价值,我们选择的任何孩子都必须像 Information,information.child1,information.child2 值等有问题上传的图片 @Madpop,我更新了我的答案以制作一个“递归组件”。你的 .json 太复杂了。我建议您将其更改为更“简单”(也许您可以使用您的 json 转换递归组件的示例-我懒得这样做-) 我们可以在其中插入复选框吗?

以上是关于如何使用 Angular 6 和 bootstrap 3.3.7 创建带有复选框列表的可折叠/可扩展/树结构的主要内容,如果未能解决你的问题,请参考以下文章

angular 分页

如何在角度 2 中使用引导程序 4?

Angular:如何使用 RXJS 6 调用 finally()

Angular Scope解析与应用

如何使用 jwt 在 Angular 6 和 web api 中刷新令牌?

如何在 Angular(6) 和 firebase Firestore 设置中分页返回前一页