如何在Angle&Bootstrap 3.3.7中为父母和孩子应用复选框

时间:2018-12-09 14:57:04

标签: javascript angular twitter-bootstrap typescript twitter-bootstrap-3

这是我的要求:-

当我单击父级时,它的子级元素也会被选中,并且在此我们也可以取消选择我们不想要的子级。然后单击按钮,我们必须将选定的父母和孩子的姓名作为  对象

我到目前为止所做的:-

我创建了父母和孩子的列表,并为父母提供了复选框,并在选中n并取消选中并获取值后获取了父母的值

卡住了,我该如何选择该父级中的子级并获取父级和子级的值

下面是我的代码

.ts

 @ViewChildren('myItem') item;
  selectedIds = [];
 display:any;
 data:any;

  ngOnInit(){


    // dynamic json 

    this.data = {
  "info": {
    "laptop": {
    },
    "config": {
      "properties": {
        "ram": {
        },
        "processor": {
        },
        "hdd": {

        }
      }
    },
    "link": {

    },
    "name": {

    },
    "company": {
      "properties": {
        "model": {

        },
        "maker": {
          "type": "integer"
        },
        "country": {
          "type": "text"
        },
        "enterprise": {

        }

      }
    }
  }
};


  // varible 

    this.display = this.data['info'];
    console.log(this.display);

  }

  change(data,event){
 if (event.target.checked === true) {
      this.selectedIds.push({id: data, checked: event.target.checked});
      console.log('Selected data ', JSON.stringify(this.selectedIds));
    }
    if (event.target.checked === false) {
      this.selectedIds = this.selectedIds.filter((item) => item.id !== data);
    }


}
getData(){
      const filtered = this.selectedIds.filter(item => item.id)
 console.log(JSON.stringify(filtered));
    }

.html代码

<ul class="list-group" *ngFor="let parent of display | keyvalue">
  <li class="list-group-item">  <input  type="checkbox" [value]="parent.key" [(ngModel)]="parent.check"  #myItem  (change)="change(parent.key,$event)">{{parent.key}}</li>
 <ng-container *ngIf="parent.check && parent.value.hasOwnProperty('properties')">
      <ul *ngFor="let child of parent.value.properties | keyvalue">
      <li>
        {{child.key}}
      </li>
      </ul>  
    </ng-container> 
</ul>

<hr>

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

我的stackblitz链接

https://stackblitz.com/edit/angular-8vqwsc

parent and child

1 个答案:

答案 0 :(得分:1)

您唯一需要的就是将“子级”传递给函数

(change)="change(parent.key,parent.value.properties,$event)"

然后您的功能发生变化

  change(data, children, event) {
    if (event.target.checked === true) {
      this.selectedIds.push({ id: data, checked: event.target.checked });
      for (let child in children) {
        this.selectedIds.push({ id: child, checked: event.target.checked });
      }
    }
    if (event.target.checked === false) {
      this.selectedIds = this.selectedIds.filter((item) => item.id !== data);
      for (let child in children) {
        this.selectedIds = this.selectedIds.filter((item) => item.id !== child);
      }
    }

出现一个问题,显示所选值。为此,您需要一个函数

  isChecked(child) {
    let item = this.selectedIds.find(x => x.id == child.key)
    return item ? item.checked : false
  }

并添加(单击)到“儿童”以更改this.selected

  <ul *ngFor="let child of parent.value.properties | keyvalue">
  <li>
    <input  type="checkbox" [checked]="isChecked(child)" (change)="change(child.key,null,$event)"/>
    {{child.key}}
  </li>
  </ul>  

但是我认为有更好的方法来做这些事情。想象一下,您的数据变成了

this.data2 =[ 
  {
    "id":"laptop","checked":false
    },
    {"id":"config","checked":false,"properties": [
        {"id":"ram","checked":false},
        {"id":"processor","checked":false},
        {"id":"ram","checked":false}
      ]
    },
    {"id":"link","checked":false},
    {"id":"name","checked":false},
    {"id":"company","checked":false,"properties":[
        {"id":"model","checked":false},
        {"id":"maker","checked":false},
        {"id":"country","checked":false},
        {"id":"enterprise","checked":false}

    ]}
]

(我放了选中的属性,但这不是必需的) 您的.html变得更容易了

<ul *ngFor="let parent of data2">
  <li><input  type="checkbox" [(ngModel)]="parent.checked" (change)="changedChild(parent.checked,parent.properties)"> {{parent.id}}
      <ng-container *ngIf="parent.checked">
        <ul  *ngFor="let child of parent.properties">
      <li>
        <input  type="checkbox" [(ngModel)]="child.checked" />
        {{child.id}}
      </li>
      </ul>  
      </ng-container>
  </li>
</ul>

然后函数changedChild

changedChild(value,children)
{
   if (children)
       children.forEach(x=>x.checked=value)
}

已更新,向此对象添加对象。 功能变为

change(data, children, event) {
    if (event.target.checked === true) {
      this.selectedIds.push({ id: data, checked: event.target.checked });
      for (let child in children) {
        this.selectedIds[this.selectedIds.length-1][child]=event.target.checked;

      }
    }
    if (event.target.checked === false) {
      this.selectedIds = this.selectedIds.filter((item) => item.id !== data);
    }

}
changeChild(parentKey,childKey,event)
{
    let item:any = this.selectedIds.find(x => x.id == parentKey)
    if (event.target.checked)
      item[childKey]=event.target.checked;
    else
      delete item[childKey];

}

isChecked(parentKey,childKey) {
    let item:any = this.selectedIds.find(x => x.id == parentKey)
    return item ? item[childKey] : false
  }

还有html

<ul class="list-group" *ngFor="let parent of display | keyvalue">
  <li class="list-group-item">  <input  type="checkbox" [value]="parent.key" [(ngModel)]="parent.check"  #myItem  (change)="change(parent.key,parent.value.properties,$event)">{{parent.key}}</li>
 <ng-container *ngIf="parent.check && parent.value.hasOwnProperty('properties')">
      <ul *ngFor="let child of parent.value.properties | keyvalue">
      <li>
         <input  type="checkbox" [checked]="isChecked(parent.key,child.key)" (change)="changeChild(parent.key,child.key,$event)"/>
    {{child.key}}

      </li>
      </ul>  
    </ng-container> 
</ul>

请参见forked stackblitz