如何从json数据中过滤子菜单并绑定到angular2中的html

时间:2018-12-13 06:55:28

标签: javascript angular typescript

我有一个JSON数据,由ID和parentID组成, 现在,我需要用ID及其parentID绑定HTML中的值。 谁能帮我怎么做。

JSON数据:

(19) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
0: {ID: 1, Text: "Home / Dashboard", Description: "Home / Dashboard", ParentMenuId: 0, isChecked: true}
1: {ID: 2, Text: "User Management", Description: "User Management", ParentMenuId: 0}
2: {ID: 3, Text: "Basic Users", Description: "Basic Users", ParentMenuId: 2}
3: {ID: 4, Text: "Admin Users", Description: "Admin Users", ParentMenuId: 2}
4: {ID: 5, Text: "Dicom", Description: "Dicom", ParentMenuId: 0}
5: {ID: 6, Text: "EMR", Description: "EMR", ParentMenuId: 0}
6: {ID: 7, Text: "Case Management", Description: "Case Management", ParentMenuId: 0}
7: {ID: 8, Text: "System Settings", Description: "System Settings", ParentMenuId: 0}
8: {ID: 9, Text: "Deployment", Description: "Deployment", ParentMenuId: 0}
9: {ID: 10, Text: "Environment", Description: "Environment", ParentMenuId: 0}
10: {ID: 12, Text: "Lookup Master", Description: "Lookup Master", ParentMenuId: 8}
11: {ID: 13, Text: "User Authorization", Description: "User Authorization", ParentMenuId: 8}
12: {ID: 14, Text: "Report", Description: "Report", ParentMenuId: 0, isChecked: true}
13: {ID: 15, Text: "Admin Authorization", Description: "Admin Authorization", ParentMenuId: 8}
14: {ID: 16, Text: "Multilingual Master", Description: "Multilingual Master", ParentMenuId: 8}
15: {ID: 17, Text: "Cache Server", Description: "Cache Server", ParentMenuId: 10, isChecked: true}
16: {ID: 18, Text: "Cache Details", Description: "Cache Details", ParentMenuId: 10, isChecked: true}
17: {ID: 19, Text: "Data Storage", Description: "Data Storage", ParentMenuId: 10}
18: {ID: 20, Text: "Viewers", Description: "Viewers", ParentMenuId: 10}
length: 19
: Array(0)

TS:

getMenu() {
    this._Service.getMenu()
      .subscribe(res => {
        this.userMenu = res.Body.Data
      })
  }

HTML:

 <div>
      <div id="accordion" class="panel-group">
        <ul class="metismenu" id="menu">
          <li class="m--5" *ngFor="let menu of userMenu">
            <a class="nav-link">
              <input type="checkbox" [checked]="menu.isChecked" (click)="selectedMenu($event.target.checked, menu.ID)">
              <span class="nav-text p-l10">{{menu.Text}}</span>
            </a>
          </li>
        </ul>
      </div>
    </div>
  1. 所以,在这里,我希望父级位于顶部,子级必须在父级的正下方,并带有制表符空间。
  2. 选中子项后,还应自动选中父项。

我的要求是:

enter image description here

但是我是这样的:

enter image description here

Demo Link

1 个答案:

答案 0 :(得分:1)

简单的方法是根据菜单ID对其进行过滤,并嵌套ul->li

<ul class="metismenu" id="menu">
    <li class="m--5" *ngFor="let menu of userMenu">
        <a class="nav-link">
            <input type="checkbox" [checked]="menu.isChecked" (click)="selectedMenu($event.target.checked, menu.ID)">
            <span class="nav-text p-l10">{{menu.Text}}
            <ul>
                <li *ngFor="let submenu of subUserMenu(menu.ID)">
                    <input type="checkbox" [checked]="submenu.isChecked" (click)="selectedMenu($event.target.checked, submenu.ID)">
                    <i class="fa fa-circle-o"></i> {{submenu.Text}}
                </li>
            </ul>
            </span>  
        </a>
    </li>
</ul>

subUserMenu(menuId){
    return  this.userMenu.filter(x=>x.ParentMenuId===menuId);
}

更新:

添加了一个属性以获取父用户菜单。因此,您将在其中循环浏览。

get parentUserMenu(){
    return this.userMenu.filter(x=>x.ParentMenuId===0);
}

<ul class="metismenu" id="menu">
    <li class="m--5" *ngFor="let menu of parentUserMenu">
        <a class="nav-link">
            ...

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

更新2:

checkParent(id){
    const item = this.userMenu.find(x=>x.ID == id);
    if(item.ParentMenuId !== 0){
        let parent = this.userMenu.find(x=>x.ID===item.ParentMenuId)
        if(parent.isChecked === undefined || parent.isChecked===false){
            parent.isChecked = true;
            this.selectedMenuIds.push(parent.ID);
        }
    }
}

unCheckParent(id){
    const item = this.userMenu.find(x=>x.ID == id);
    if(item.ParentMenuId !== 0){
        var siblings = this.userMenu.filter(x=>x.ParentMenuId === item.ParentMenuId);
        if(siblings.filter(x=>x.isChecked===true).length === 0){
            let parent = this.userMenu.find(x=>x.ID == item.ParentMenuId);
            parent.isChecked = false;
            this.selectedMenuIds.splice(this.selectedMenuIds.indexOf(parent.ID), 1);
        }
    }
}

因此,当选中一个复选框时,您会找到父项并对其进行检查(如果尚未选中),并且在取消选中最后一个子项时也进行同样的操作。

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

更新3: 基本上,您会找到所有孩子并选中/取消选中所有孩子,然后将他们推入/拼接在一起

//'check all child'
let childs = this.userMenu.filter(x=>x.ParentMenuId === item.ID);
childs.forEach(x=>{
    x.isChecked = true;
    this.selectedMenuIds.push(x.ID);
});

//uncheck all child
let childs = this.userMenu.filter(x=>x.ParentMenuId === item.ID);
childs.forEach(x=>{
    x.isChecked = false;
    this.selectedMenuIds.splice(this.selectedMenuIds.indexOf(x.ID), 1);
});

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