代码之家  ›  专栏  ›  技术社区  ›  Bhrungarajni

如何从json数据中筛选子菜单并在angular2中绑定到html

  •  0
  • Bhrungarajni  · 技术社区  · 5 年前

    我有一个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 回复  |  直到 5 年前
        1
  •  1
  •   j4rey    5 年前

    简单的方法是根据菜单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

    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