如何使batchEdit也可用于json嵌套节点? [英] How can I make batchEdit available for json nested nodes as well?

查看:59
本文介绍了如何使batchEdit也可用于json嵌套节点?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好Stackoverflow成员

我也想使批量编辑也可用于子节点,但我无法实现.

任何人都可以查看代码并向我提出更改建议,以便批量编辑可用于记录的父节点和嵌套节点.

app.component.html

 < div class ="container-fluid"><!-添加记录->< div * ngIf ="isAdd">< form#myForm ="ngForm">< div class ="form-group"><标签>名字</label><输入类型=文本";name ="first_name";class ="form-control"ngModel></div>< div class ="form-group"><标签>姓氏</label><输入类型=文本";name ="last_name";class ="form-control"ngModel></div>< div class ="form-group">< label>电子邮件</label><输入类型=电子邮件"name =电子邮件"class ="form-control"ngModel></div>< div class ="form-group"><标签>性别</标签><选择名称=性别";id ="ngModel class ="form-control"< option>男性</option>< option>女</option></select></div>< div class ="form-group"><标签<出生日期</label><输入类型=日期";name ="dob"class ="form-control"ngModel></div>< div class ="form-group">< label"影响</label>< div class ="form-check">< input class ="form-check-input";type ="radio"名称=影响";ngModel id ="impactOption1";value =适用"已检查>< label class ="form-check-label"for ="impactOption1">.适用的</label></div>< div class ="form-check">< input class ="form-check-input";type ="radio"名称=影响";ngModel id ="impactOption2";value =不适用"< label class ="form-check-label"for ="impactOption2">.不适用</label></div></div>< div class ="form-group">< label>分数</label><输入类型=数字";名称=分数"class ="form-control"ngModel></div>< div class ="form-group">< button type =按钮";class ="btn btn-primary btn-sm";(点击)="addUser(myForm.value)">提交</button>< button type =按钮";class ="btn btn-secondary btn-sm ml-2"(click)="cancelAddUser()"> Cancel</button></div></form></div><!-添加记录-><!-父批编辑->< div>< form#myForm ="ngForm">< div class ="form-group"><选择名称=影响";[disabled] =!isBatchEdit"class ="form-control form-control-sm".[(ngModel)] ="currentImpact".<选项值="禁用已选择>更改影响</option>< option>适用</option>< option>不适用</option>< option> FYI</option></select></div>< button type =按钮";[disabled] =!isBatchEdit"(click)=" batchUpdateUser();myForm.reset()";class ="btn btn-成功btn-sm btn-update mr-2">更新</button>< button type =按钮";[disabled] =!isBatchEdit"(click)=" cancelBatchEdit();myForm.reset()";class ="btn btn-secondary btn-sm">取消/按钮.</form></div><!-父批编辑-><!-单个记录编辑->< div * ngIf ="isEdit">< form#myForm ="ngForm">< div class ="form-group"><选择名称=影响";id ="class ="form-control form-control-sm".[(ngModel)] ="currentImpact".< option>适用</option>< option>不适用</option>< option> FYI</option></select></div>< button type =按钮";(click)="updateUser()";class ="btn btn-成功btn-sm btn-update mr-2".* ngIf ="isEdit"> Update</button>< button type =按钮";(click)="cancelEdit()";class ="btn btn-secondary btn-sm">取消/按钮.</form></div><!-单个记录编辑-><!-过滤器->< div class ="filter-data mt-3">< form#form ="ngForm">< div class ="form-group float-left mr-4"< strong>性别</strong>< br><选择类="form-control form-control-sm";名称=性别"ngModel [ngModelOptions] =" {updateOn:'submit'}">< option></option>< option value ="Male"> Male</option>< option value =女性">女性</option></select></div>< div class ="form-group float-left"< strong>影响力</strong>< br><选择类="form-control form-control-sm";名称=影响";ngModel [ngModelOptions] =" {updateOn:'submit'}">< option></option>< option value =适用">适用</option>< option value =不适用">不适用</option></select></div>< div class ="form-group float-left mt-3 pt-1 ml-2"< button type =提交";class ="btn btn-primary btn-sm mr-2">应用/按钮.< button type =按钮";(click)="form.reset();";class ="btn btn-secondary btn-sm">重置</button>.</div></form></div><!-过滤器->< div class ="clearfix"</div<!-父视图表->< div class ="viewData">< div class ="float-left">< button class ="btn btn-primary btn-sm mb-2 mt-2";(点击)="showAddUser()">添加新记录</button></div>< div class ="float-right"< div class =文本右总记录向右浮动">总计:{{totalRecords}}</div>< button type =按钮";class ="btn btn-sm btn-secondary float-right mr-2 mt-2 mb-2".(click)="reload()"> Refresh</button></div>< div class ="clearfix"</div< table class ="table table-sm table-response"< thead>< tr>< th</th><名字</th><姓</th>< th>电子邮件</th><性别>/th< th> DOB< th><影响>< th<分数</th>< th</th></tr></thead>< tbody>< tr class =记录行";(click)="viewUser(user)";* ngFor ="让allUser的用户|tableFilter:form.value |分页:{id:"listing_pagination",itemsPerPage:10,currentPage:页面,totalItems:totalRecords}< td><输入* ngIf =!isEdit"[(ngModel)] ="user.checked";type ="checkbox"(change)="checkboxClicked()"</td>< td> {{user.first_name}}</td>< td> {{user.last_name}}</td>< td> {{user.email}}</td>< td> {{user.gender}}</td>< td> {{user.dob}}</td>< td> {{user.impact}}</td>< td>< div [ngClass] =" getClass(user)"> {{user.score}}</div></td>< td>< button * ngIf ="!isEdit"class ="btn btn-primary btn-sm";(点击)="editUser(用户)">编辑</button><按钮类="btn btn-主btn-sm btn-sm ml-2".(点击)="deleteUser(用户)"< Delete</button></td></tr></tbody></table>< pagination-controls id ="listing_pagination";directionLinks ="true"(pageChange)="page = $ event"</pagination-controls></div><!-父视图表->< div class ="clearfix"</div<!-记录详细信息视图->< div * ngIf ="isView"class ="view-details"< ul class =卡片p-2">< li>< strong>名</strong>< br/>{{userObj.first_name}}</li>< li>< strong>姓氏</strong>< br/>{{userObj.last_name}}</li>< li>< strong>电子邮件</strong>< br/>{{userObj.email}}</li>< li>< strong>性别</strong>< br/>{{userObj.gender}}</li>< li>< strong> IP地址</strong>< br/>{{userObj.dob}}</li>< li< strong>影响力</strong>< br/>{{userObj.impact}}</li>< li>< strong"分数</strong>< br/>< span [ngClass] =" getClass(userObj)" {{userObj.score}}</span</li></ul>< div class ="clearfix"</div< div class ="mb-3">< form#myForm ="ngForm">< div class ="form-group"><选择名称=影响";[disabled] =!isSubBatchEdit"class ="form-control form-control-sm".[(ngModel)] ="currentImpact".<选项值="禁用已选择>更改影响</option>< option>适用</option>< option>不适用</option>< option> FYI</option></select></div>< button type =按钮";[disabled] =!isSubBatchEdit"(click)="subBatchUpdateUser();myForm.reset()";class ="btn btn-成功btn-sm btn-update mr-2">更新</button>< button type =按钮";[disabled] =!isSubBatchEdit"(click)=" subCancelBatchEdit();myForm.reset()";class ="btn btn-secondary btn-sm">取消/按钮.</form></div>< div class ="clearfix"</div<表类=表表响应表-sm">< thead>< tr>< th</th>< th> CO得分</th>< th>分发列表</th><影响>< th>评论</th></tr></thead>< tbody>< tr * ngFor =让userObj.assigned_to的受让人"< td><输入* ngIf =!isEdit"[(ngModel)] ="assignee.checked";type ="checkbox"(change)="subCheckboxClicked()"</td>< td>< div [ngClass] ="getClass(assignee)"> {{assignee.co_score}}</div</td>< td> {{assignee.dl}}</td>< td> {{assignee.sub_impact}}</td>< td> {{assignee.comments}}</td></tr></tbody></table>< div class ="clearfix">//div< div class ="viewChart">< div class =技能">< ul class =标签">< li>适用</li>< li>不适用</li>< li> FYI</li></ul>< ul class =行">< li class =线l-0">< span class ="line_label"< 0lt/span>/li>< li class ="line 1--1">&span class ="line__label"< 1/span</li>< li class =" line 1--2"> span class ="line__label"< 2/span</li>< li class ="line 1--3">< span class ="line_label"< 3</span</li>< li class =" line 1--4"> span class ="line__label"< 4</span</li>< li class ="line 1--5">< span class ="line_label"> 5</span</li>< li class =" line 1--6"> span class ="line__label"< 6/span</li>"li class =" line 1--7">"span class =" line__label""7 /li< li class =" line 1--8">&span class ="line_label"< 8</span</li>"li class =" line 1--9">"span class =" line__label"> 9 /li.</ul>< div class =图表">< div class =图表图表--dev">< ul class ="chart--horiz">< li class ="chart__bar";[style.width] ="impactCount.applicable * 10 +'%'"> {{impactCount.applicable}}</li;< li class ="chart__bar";[style.width] ="impactCount.notapplicable * 10 +'%'"> {{impactCount.notapplicable}}</li>< li class ="chart__bar";[style.width] ="impactCount.fyi * 10 +'%'"> {{impactCount.fyi}}</li></ul></div></div></div></div></div><!-记录详细信息视图-></div> 

app.component.ts

 从'@ angular/core'导入{组件};从"./common.service"导入{CommonService};从"@ angular/forms"导入{NgForm};@零件({选择器:"app-root",templateUrl:"./app.component.html",styleUrls:['./app.component.scss']})导出类AppComponent {title ='db-poc1';allUser:任何;isEdit = false;isView = false;isBatchEdit = false;isSubBatchEdit = false;isAdd = false;totalRecords:任意;页面:数字= 1;currentImpact:字符串='';batchUpdateUsers = [];subBatchUpdateUsers = [];userObj = {id:'',first_name:'',last_name:'',电子邮件:'',性别:'',dob:'',影响:'',得分:''}impactCount = {适用:0,不适用:0,fyi:0}构造函数(私有commonService:CommonService){}ngOnInit(){this.getLatestUser();}reload(){window.location.reload();}checkboxClicked(){this.batchUpdateUsers = this.allUser.filter((row:any)=> row.checked);this.isView = true;this.isBatchEdit = this.batchUpdateUsers.length>0;this.currentImpact = this.userObj.impact;}subCheckboxClicked(){this.subBatchUpdateUsers = this.allUser.filter((row:any)=> row.checked);this.isView = true;this.isSubBatchEdit = this.subBatchUpdateUsers.length>0;this.currentImpact = this.userObj.impact;}addUser(formObj:any){this.commonService.createUser(formObj).subscribe((response)=> {this.getLatestUser();});this.isAdd = false;}showAddUser(){this.isAdd = true;}cancelAddUser(){this.isAdd = false;}getLatestUser(){this.commonService.getAllUser().subscribe((response)=> {this.allUser =响应;this.totalRecords = this.allUser.length;this.getApplicableCounts();this.allUser.forEach((row:any)=> row.checked = false);});}getApplicableCounts(){this.impactCount = {applyable:0,notapplicable:0,fyi:0}this.allUser.forEach((row:any)=> {//this.allUser.forEach(row => {//如果(row.impact ==='适用'){//this.impactCount.applicable ++;//} else if(row.impact ==='不适用'){//this.impactCount.notapplicable ++;//} else if(row.impact ==='FYI'){//this.impactCount.fyi ++;//}//});row.assigned_to.forEach((sub:any)=> {如果(sub.sub_impact ==='适用'){this.impactCount.applicable ++;}否则,如果(sub.sub_impact ==='不适用'){this.impactCount.notapplicable ++;}否则,如果(sub.sub_impact ==='FYI'){this.impactCount.fyi ++;}});});}editUser(用户:任何){this.isEdit = true;this.userObj =用户;this.allUser.forEach(user => user.checked = false);this.currentImpact = user.impact;}deleteUser(user:any){this.commonService.deleteUser(user).subscribe(()=> {this.getLatestUser();});}updateUser(){this.isEdit =!this.isEdit;this.userObj.impact = this.currentImpact;this.commonService.updateUser(this.userObj).subscribe(()=> {this.getLatestUser();});this.getApplicableCounts();}cancelEdit(){this.isEdit = false;this.isView = false;}viewUser(user:any){this.isView = true;this.userObj =用户;}cancelBatchEdit(){this.isBatchEdit = false;this.allUser.forEach((user:any)=> {user.checked = false});}getClass(用户){if(user.score< = 30 || user.co_score< = 30)返回初学者";否则,如果(user.score< = 75 || user.co_score< = 75)返回中级";否则,如果(user.score< = 100 || user.co_score< = 100)返回专家";否则返回其他";}batchUpdateUser(){this.isBatchEdit = false;const batchUpdateUserList = [];this.allUser.forEach((user:any)=> {如果(经过用户检查){user.impact = this.currentImpactbatchUpdateUserList.push(user);user.checked = false;this.commonService.updateUser(user).subscribe(()=> {this.getLatestUser();});user.score =已更新";}});this.commonService.updateUser(this.userObj).subscribe(()=> {this.getLatestUser();});this.getApplicableCounts();}subBatchUpdateUser(){this.isSubBatchEdit = false;const subBatchUpdateUserList = [];this.allUser.forEach((user:any)=> {如果(user.sub_impact.checked){user.sub_impact.impact = this.currentImpactsubBatchUpdateUserList.push(user);user.sub_impact.checked = false;this.commonService.updateUser(user).subscribe(()=> {this.getLatestUser();});user.score =已更新";}});this.commonService.updateUser(this.userObj).subscribe(()=> {this.getLatestUser();});this.getApplicableCounts();}subCancelBatchEdit(){this.isSubBatchEdit = false;this.allUser.forEach((user:any)=> {user.checked = false});}} 

db.json

  {用户":[{"id":1,"first_name":"Male","last_name":"Record",电子邮件":"male.record@gmail.com",性别":男性","dob":"01-01-1987",影响":不适用",得分":已更新",已检查":否,"assigned_to":[{"co_score":54"dl":"CAT1","sub_impact":适用",已检查":否,注释":"Lorem Ipsum"只是印刷和排版行业的伪文本.自1500年代以来,Lorem Ipsum一直是行业的标准伪文本,当时一位不知名的打印机拿起一个样板间,然后将其打乱成样本.},{"co_score":20,"dl":"CAT2","sub_impact":不适用",已检查":否,注释":"Lorem Ipsum"只是印刷和排版行业的伪文本.自1500年代以来,Lorem Ipsum一直是行业的标准伪文本,当时一位不知名的打印机拿起一个样板间,然后将其打乱成样本.},{"co_score":99,"dl":"CAT1","sub_impact":适用",已检查":否,注释":"Lorem Ipsum"只是印刷和排版行业的伪文本.自1500年代以来,Lorem Ipsum一直是行业的标准伪文本,当时一位不知名的打印机拿起一个样板间,然后将其打乱成样本.}]},{"id":2"first_name":"Female","last_name":"Record",电子邮件":"female.record@gmail.com",性别":女性","dob":"31-12-1987",影响":适用",已检查":否,得分":已更新","assigned_to":[{"co_score":54"dl":"CAT1","sub_impact":适用",已检查":否,注释":"Lorem Ipsum"只是印刷和排版行业的伪文本.自1500年代以来,Lorem Ipsum一直是行业的标准伪文本,当时一位不知名的打印机拿起一个样板间,然后将其打乱成样本.},{"co_score":20,"dl":"CAT2","sub_impact":不适用",已检查":否,注释":"Lorem Ipsum"只是印刷和排版行业的伪文本.自1500年代以来,Lorem Ipsum一直是行业的标准伪文本,当时一位不知名的打印机拿起一个样板间,然后将其打乱成样本.}]},{"id":3,"first_name":"Male","last_name":"Record Another",电子邮件":"male.recordanother@gmail.com",性别":男性","dob":"31-10-2017",影响":适用",已检查":否,分数":25,"assigned_to":[{"co_score":100,"dl":"CAT3","sub_impact":适用",已检查":否,注释":"Lorem Ipsum"只是印刷和排版行业的伪文本.自1500年代以来,Lorem Ipsum一直是行业的标准伪文本,当时一位不知名的打印机拿起一个样板间,然后将其打乱成样本.},{"co_score":2"dl":"CAT2","sub_impact":不适用",已检查":否,注释":"Lorem Ipsum"只是印刷和排版行业的伪文本.自1500年代以来,Lorem Ipsum一直是行业的标准伪文本,当时一位不知名的打印机拿起一个样板间,然后将其打乱成样本.},{"co_score":48​​,"dl":"CAT2","sub_impact":不适用",已检查":否,注释":"Lorem Ipsum"只是印刷和排版行业的伪文本.自1500年代以来,Lorem Ipsum一直是行业的标准伪文本,当时一位不知名的打印机拿起一个样板间,然后将其打乱成样本.}]},{"first_name":"Male","last_name":一个更多的记录",电子邮件":"male.onemorerecord@gmail.com",性别":男性","dob":"08-08-1984",影响":适用","id":6已检查":否,得分":已更新","assigned_to":[{"co_score":4,"dl":"CAT1","sub_impact":适用",已检查":否,注释":"Lorem Ipsum"只是印刷和排版行业的伪文本.自1500年代以来,Lorem Ipsum一直是行业的标准伪文本,当时一位不知名的打印机拿起一个样板间,然后将其打乱成样本.},{"co_score":85,"dl":"CAT3","sub_impact":不适用",已检查":否,注释":"Lorem Ipsum"只是印刷和排版行业的伪文本.自1500年代以来,Lorem Ipsum一直是行业的标准伪文本,当时一位不知名的打印机拿起一个样板间,然后将其打乱成样本.}]},{"first_name":"Female","last_name":另一个记录",电子邮件":"female.anotherrecord@gmail.com",性别":女性","dob":"2000-07-15",影响":适用","id":7已检查":否,评分":85,"assigned_to":[{"co_score":34,"dl":"CAT3","sub_impact":适用",已检查":否,注释":"Lorem Ipsum"只是印刷和排版行业的伪文本.自1500年代以来,Lorem Ipsum一直是行业的标准伪文本,当时一位不知名的打印机拿起一个样板间,然后将其打乱成样本.},{"co_score":55,"dl":"CAT2","sub_impact":不适用",已检查":否,注释":"Lorem Ipsum"只是印刷和排版行业的伪文本.自1500年代以来,Lorem Ipsum一直是行业的标准伪文本,当时一位不知名的打印机拿起一个样板间,然后将其打乱成样本.}]},{"id":8"first_name":"New","last_name":"Record",电子邮件":"new.record@gmail.com",性别":男性","dob":"2020-12-17",影响":不适用",分数":60,已检查":否,"assigned_to":[{"co_score":94,"dl":"CAT1","sub_impact":不适用",已检查":否,注释":"Lorem Ipsum"只是印刷和排版行业的伪文本.自1500年代以来,Lorem Ipsum一直是行业的标准伪文本,当时一位不知名的打印机拿起一个样板间,然后将其打乱成样本.},{"co_score":85,"dl":"CAT3","sub_impact":适用",已检查":否,注释":"Lorem Ipsum"只是印刷和排版行业的伪文本.自1500年代以来,Lorem Ipsum一直是行业的标准伪文本,当时一位不知名的打印机拿起一个样板间,然后将其打乱成样本.}]}]} 

解决方案

有很多方法可以实现此目的,一种方法是:

在您的模板中:

 < tr * ngFor ="让userObj.assigned_to的受让人"< td><输入类型=复选框"[(ngModel)] ="assignee.checked"</td>< td> {{assignee.sub_impact}}</td></tr> 

并在您的组件中:

  updateUser(){this.isView =!this.isView;this.isEdit =!this.isEdit;this.userObj.impact = this.currentImpact;调试器;constcheckedItems = this.userObj.assigned_to.filter(a => a.checked);checkedItems.forEach(a => {a.sub_impact = this.currentImpact;删除a.checked;});console.log(更新");//this.commonService.updateUser().subscribe(response => {this.getCounts();//});} 

请注意,如果要在用户obj和Assigned_to之间使用不同的值,则必须创建一个新的下拉列表

这是有效的

Hi Stackoverflow Members

I wanted to make batch edit available for sub-nodes as well but I am not able to achieve it.

Can anyone please look into the code and suggest me the changes so, that batch edit is available for both parent node and nested node of record.

app.component.html

<div class="container-fluid">
  <!-- Add Record -->
  <div *ngIf="isAdd">
    <form #myForm="ngForm">
      <div class="form-group">
        <label>First Name</label>
        <input type="text" name="first_name" class="form-control" ngModel>
      </div>
      <div class="form-group">
        <label>Last Name</label>
        <input type="text" name="last_name" class="form-control" ngModel>
      </div>
      <div class="form-group">
        <label>Email</label>
        <input type="email" name="email" class="form-control" ngModel>
      </div>
      <div class="form-group">
        <label>Gender</label>
        <select name="gender" id="" ngModel class="form-control">
          <option>Male</option>
          <option>Female</option>
        </select>
      </div>
      <div class="form-group">
        <label>Date of Birth</label>
        <input type="date" name="dob" class="form-control" ngModel>
      </div>
      <div class="form-group">
        <label>Impact</label>
        <div class="form-check">
          <input class="form-check-input" type="radio" name="impact" ngModel id="impactOption1" value="Applicable" checked>
          <label class="form-check-label" for="impactOption1">
            Applicable
          </label>
        </div>
        <div class="form-check">
          <input class="form-check-input" type="radio" name="impact" ngModel id="impactOption2" value="Not Applicable">
          <label class="form-check-label" for="impactOption2">
            Not Applicable
          </label>
        </div>
      </div>
      <div class="form-group">
        <label>Score</label>
        <input type="number" name="score" class="form-control" ngModel>
      </div>
      <div class="form-group">
        <button type="button" class="btn btn-primary btn-sm" (click)="addUser(myForm.value)">Submit</button>
        <button type="button" class="btn btn-secondary btn-sm ml-2" (click)="cancelAddUser()">Cancel</button>
      </div>
    </form>
  </div>
  <!-- Add Record -->
  <!-- Parent Batch Edit -->
  <div>
    <form #myForm="ngForm">
      <div class="form-group">
        <select name="impact" [disabled]="!isBatchEdit" class="form-control form-control-sm" [(ngModel)]="currentImpact">
          <option value="" disabled selected>Change Impact</option>
          <option>Applicable</option>
          <option>Not Applicable</option>
          <option>FYI</option>
        </select>
      </div>
      <button type="button" [disabled]="!isBatchEdit" (click)="batchUpdateUser(); myForm.reset()" class="btn btn-success btn-sm btn-update mr-2">
        Update
        </button>
      <button type="button" [disabled]="!isBatchEdit" (click)="cancelBatchEdit(); myForm.reset()" class="btn btn-secondary btn-sm">Cancel</button>
    </form>
  </div>
  <!-- Parent Batch Edit -->
  <!-- Single Record Edit -->
  <div *ngIf="isEdit">
    <form #myForm="ngForm">
      <div class="form-group">
        <select name="impact" id="" class="form-control form-control-sm" [(ngModel)]="currentImpact">
          <option>Applicable</option>
          <option>Not Applicable</option>
          <option>FYI</option>
        </select>
      </div>
      <button type="button" (click)="updateUser()" class="btn btn-success btn-sm btn-update mr-2" *ngIf="isEdit">Update</button>
      <button type="button" (click)="cancelEdit()" class="btn btn-secondary btn-sm">Cancel</button>
    </form>
  </div>
  <!-- Single Record Edit -->
  <!-- Filter -->
  <div class="filter-data mt-3">
    <form #form="ngForm">
      <div class="form-group float-left mr-4">
        <strong>Gender</strong>
        <br>
        <select class="form-control form-control-sm" name="gender" ngModel [ngModelOptions]="{updateOn: 'submit'}">
          <option></option>
          <option value="Male">Male</option>
          <option value="Female">Female</option>
        </select>
      </div>
      <div class="form-group float-left">
        <strong>Impact</strong>
        <br>
        <select class="form-control form-control-sm" name="impact" ngModel [ngModelOptions]="{updateOn: 'submit'}">
          <option></option>
          <option value="Applicable">Applicable</option>
          <option value="Not Applicable">Not Applicable</option>
        </select>
      </div>
      <div class="form-group float-left mt-3 pt-1 ml-2">
        <button type="submit" class="btn btn-primary btn-sm mr-2">Apply</button>
        <button type="button" (click)="form.reset();" class="btn btn-secondary btn-sm">Reset</button>
      </div>
    </form>
  </div>
  <!-- Filter -->
  <div class="clearfix"></div>
  <!-- Parent View Table -->
  <div class="viewData">
    <div class="float-left">
      <button class="btn btn-primary btn-sm mb-2 mt-2" (click)="showAddUser()">Add New Record</button>
    </div>
    <div class="float-right">
      <div class="text-right total-records float-right">Total: {{totalRecords}}</div>
      <button type="button" class="btn btn-sm btn-secondary float-right mr-2 mt-2 mb-2" (click)="reload()">Refresh</button>
    </div>
    <div class="clearfix"></div>
    <table class="table table-sm table-responsive">
      <thead>
        <tr>
          <th></th>
          <th>First Name</th>
          <th>Last Name</th>
          <th>Email</th>
          <th>Gender</th>
          <th>DOB</th>
          <th>Impact</th>
          <th>Score</th>
          <th></th>
        </tr>
      </thead>
      <tbody>
        <tr class="record-row" (click)="viewUser(user)" *ngFor="let user of allUser | tableFilter: form.value | paginate: { id: 'listing_pagination', itemsPerPage: 10, currentPage: page, totalItems: totalRecords }">
          <td><input *ngIf="!isEdit" [(ngModel)]="user.checked" type="checkbox" (change)="checkboxClicked()"></td>
          <td>{{user.first_name}}</td>
          <td>{{user.last_name}}</td>
          <td>{{user.email}}</td>
          <td>{{user.gender}}</td>
          <td>{{user.dob}}</td>
          <td>{{user.impact}}</td>
          <td>
            <div [ngClass]="getClass(user)">{{user.score}}</div>
          </td>
          <td>
            <button *ngIf="!isEdit" class="btn btn-primary btn-sm" (click)="editUser(user)">Edit</button>
            <button class="btn btn-primary btn-sm btn-sm ml-2" (click)="deleteUser(user)">Delete</button>
          </td>
        </tr>
      </tbody>
    </table>
    <pagination-controls id="listing_pagination" directionLinks="true" (pageChange)="page = $event"></pagination-controls>
  </div>
  <!-- Parent View Table -->
  <div class="clearfix"></div>
  <!-- Record Detail View -->
  <div *ngIf="isView" class="view-details">
    <ul class="card p-2">
      <li><strong>First Name</strong> <br />{{userObj.first_name}}</li>
      <li><strong>Last Name</strong> <br />{{userObj.last_name}}</li>
      <li><strong>Email</strong> <br />{{userObj.email}}</li>
      <li><strong>Gender</strong> <br />{{userObj.gender}}</li>
      <li><strong>IP Address</strong> <br />{{userObj.dob}}</li>
      <li><strong>Impact</strong> <br />{{userObj.impact}}</li>
      <li><strong>Score</strong> <br /><span [ngClass]="getClass(userObj)">{{userObj.score}}</span></li>
    </ul>
    <div class="clearfix"></div>
    <div class="mb-3">
      <form #myForm="ngForm">
        <div class="form-group">
          <select name="impact" [disabled]="!isSubBatchEdit" class="form-control form-control-sm" [(ngModel)]="currentImpact">
            <option value="" disabled selected>Change Impact</option>
            <option>Applicable</option>
            <option>Not Applicable</option>
            <option>FYI</option>
          </select>
        </div>
        <button type="button" [disabled]="!isSubBatchEdit" (click)="subBatchUpdateUser(); myForm.reset()" class="btn btn-success btn-sm btn-update mr-2">
          Update
          </button>
        <button type="button" [disabled]="!isSubBatchEdit" (click)="subCancelBatchEdit(); myForm.reset()" class="btn btn-secondary btn-sm">Cancel</button>
      </form>
    </div>
    <div class="clearfix"></div>
    <table class="table table-responsive table-sm">
      <thead>
        <tr>
          <th></th>
          <th>CO Score</th>
          <th>Distribution List</th>
          <th>Impact</th>
          <th>Comments</th>
        </tr>
      </thead>
      <tbody>
        <tr *ngFor="let assignee of userObj.assigned_to">
          <td><input *ngIf="!isEdit" [(ngModel)]="assignee.checked" type="checkbox" (change)="subCheckboxClicked()"></td>
          <td><div [ngClass]="getClass(assignee)">{{assignee.co_score}}</div></td>
          <td>{{assignee.dl}}</td>
          <td>{{assignee.sub_impact}}</td>
          <td>{{assignee.comments}}</td>
        </tr>
      </tbody>
    </table>
    <div class="clearfix"></div>
    <div class="viewChart">
      <div class="skills">
        <ul class="labels">
          <li>Applicable</li>
          <li>Not Applicable</li>
          <li>FYI</li>
        </ul>
        <ul class="lines">
          <li class="line l--0"><span class="line__label">0</span></li>
          <li class="line l--1"><span class="line__label">1</span></li>
          <li class="line l--2"><span class="line__label">2</span></li>
          <li class="line l--3"><span class="line__label">3</span></li>
          <li class="line l--4"><span class="line__label">4</span></li>
          <li class="line l--5"><span class="line__label">5</span></li>
          <li class="line l--6"><span class="line__label">6</span></li>
          <li class="line l--7"><span class="line__label">7</span></li>
          <li class="line l--8"><span class="line__label">8</span></li>
          <li class="line l--9"><span class="line__label">9</span></li>
        </ul>
        <div class="charts">
          <div class="chart chart--dev">
            <ul class="charts--horiz">
              <li class="chart__bar" [style.width]="impactCount.applicable * 10 + '%'">{{impactCount.applicable}}</li>
              <li class="chart__bar" [style.width]="impactCount.notapplicable * 10 + '%'">{{impactCount.notapplicable}}</li>
              <li class="chart__bar" [style.width]="impactCount.fyi * 10 + '%'">{{impactCount.fyi}}</li>
            </ul>
          </div>
        </div>
      </div>
    </div>
  </div>
  <!-- Record Detail View -->
</div>

app.component.ts

import { Component } from '@angular/core';
import { CommonService } from './common.service';
import { NgForm } from '@angular/forms';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})

export class AppComponent {
  title = 'db-poc1';
  allUser: any;
  isEdit = false;
  isView = false;
  isBatchEdit = false;
  isSubBatchEdit = false;
  isAdd = false;
  totalRecords: any;
  page: Number = 1;
  currentImpact: string = '';
  batchUpdateUsers = [];
  subBatchUpdateUsers = [];

  userObj = {
    id: '', first_name: '', last_name: '', email: '', gender: '', dob: '', impact: '', score: ''
  }

  impactCount = {
    applicable: 0, notapplicable: 0, fyi: 0 
  }

  constructor(private commonService: CommonService) {}

  ngOnInit() {
    this.getLatestUser();
  }

  reload() {
    window.location.reload();
  }

  checkboxClicked() {
    this.batchUpdateUsers = this.allUser.filter((row: any) => row.checked);
    this.isView  = true;
    this.isBatchEdit = this.batchUpdateUsers.length > 0;
    this.currentImpact = this.userObj.impact;
  }

  subCheckboxClicked() {
    this.subBatchUpdateUsers = this.allUser.filter((row: any) => row.checked);    
    this.isView  = true;
    this.isSubBatchEdit = this.subBatchUpdateUsers.length > 0;
    this.currentImpact = this.userObj.impact;
  }

  addUser(formObj: any) {
    this.commonService.createUser(formObj).subscribe((response) => {
      this.getLatestUser();
    });
    this.isAdd = false;
  }

  showAddUser() {
    this.isAdd = true;
  }
  
  cancelAddUser() {
    this.isAdd = false;
  }

  getLatestUser() {
    this.commonService.getAllUser().subscribe((response) => {
      this.allUser = response;
      this.totalRecords = this.allUser.length;
      this.getApplicableCounts();
      this.allUser.forEach((row: any) => row.checked = false);
    });
  }

  getApplicableCounts() {
    this.impactCount = {applicable:0, notapplicable:0, fyi: 0}
    this.allUser.forEach((row: any) => {
      // this.allUser.forEach(row => {
      //   if (row.impact === 'Applicable') {
      //     this.impactCount.applicable++;
      //   } else if (row.impact === 'Not Applicable') {
      //     this.impactCount.notapplicable++;
      //   } else if (row.impact === 'FYI') {
      //     this.impactCount.fyi++;
      //   }
      // });
      row.assigned_to.forEach((sub: any) => {
        if (sub.sub_impact === 'Applicable') {
          this.impactCount.applicable++;
        } else if (sub.sub_impact === 'Not Applicable') {
          this.impactCount.notapplicable++;
        } else if (sub.sub_impact === 'FYI') {
          this.impactCount.fyi++;
        }
      });
    });
  }

  editUser(user: any) {
    this.isEdit = true;
    this.userObj = user;
    this.allUser.forEach(user => user.checked = false);
    this.currentImpact = user.impact;
  }

  deleteUser(user: any) {
    this.commonService.deleteUser(user).subscribe(() => {
      this.getLatestUser();
    });
  }

  updateUser() {
    this.isEdit = !this.isEdit;
    this.userObj.impact = this.currentImpact;
    this.commonService.updateUser(this.userObj).subscribe(() => {
      this.getLatestUser();
    });
    this.getApplicableCounts();
  }

  cancelEdit() {
    this.isEdit = false;
    this.isView = false;
  }

  viewUser(user: any) {
    this.isView = true;
    this.userObj = user;
  }

  cancelBatchEdit() {
    this.isBatchEdit = false;
    this.allUser.forEach((user: any) => {user.checked = false});
  }

  getClass(user) {
    if(user.score <= 30 || user.co_score <= 30)
    return 'beginner';
    else if (user.score <= 75 || user.co_score <= 75)
    return 'intermediate';
    else if (user.score <= 100 || user.co_score <= 100)
    return 'expert';
    else return 'other';
  }

  batchUpdateUser() {
    this.isBatchEdit = false;
    const batchUpdateUserList = [];
    this.allUser.forEach((user: any) => {
      if (user.checked) {
        user.impact = this.currentImpact
        batchUpdateUserList.push(user);
        user.checked = false;
        this.commonService.updateUser(user).subscribe(() => {
          this.getLatestUser();
        });
        user.score = "Updated";
      }
    });
    this.commonService.updateUser(this.userObj).subscribe(() => {
      this.getLatestUser();
    });
    this.getApplicableCounts();
  }

  subBatchUpdateUser() {
    this.isSubBatchEdit = false;
    const subBatchUpdateUserList = [];
    this.allUser.forEach((user: any) => {
      if (user.sub_impact.checked) {
        user.sub_impact.impact = this.currentImpact
        subBatchUpdateUserList.push(user);
        user.sub_impact.checked = false;
        this.commonService.updateUser(user).subscribe(() => {
          this.getLatestUser();
        });
        user.score = "Updated";
      }
    });
    this.commonService.updateUser(this.userObj).subscribe(() => {
      this.getLatestUser();
    });
    this.getApplicableCounts();
  }

  subCancelBatchEdit() {
    this.isSubBatchEdit = false;
    this.allUser.forEach((user: any) => {user.checked = false});
  }
}

db.json

{
  "users": [
    {
      "id": 1,
      "first_name": "Male",
      "last_name": "Record",
      "email": "male.record@gmail.com",
      "gender": "Male",
      "dob": "01-01-1987",
      "impact": "Not Applicable",
      "score": "Updated",
      "checked": false,
      "assigned_to": [
        {
          "co_score": 54,
          "dl": "CAT1",
          "sub_impact": "Applicable",
          "checked": false,
          "comments": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book."
        },
        {
          "co_score": 20,
          "dl": "CAT2",
          "sub_impact": "Not Applicable",
          "checked": false,
          "comments": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book."
        },
        {
          "co_score": 99,
          "dl": "CAT1",
          "sub_impact": "Applicable",
          "checked": false,
          "comments": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book."
        }
      ]
    },
    {
      "id": 2,
      "first_name": "Female",
      "last_name": "Record",
      "email": "female.record@gmail.com",
      "gender": "Female",
      "dob": "31-12-1987",
      "impact": "Applicable",
      "checked": false,
      "score": "Updated",
      "assigned_to": [
        {
          "co_score": 54,
          "dl": "CAT1",
          "sub_impact": "Applicable",
          "checked": false,
          "comments": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book."
        },
        {
          "co_score": 20,
          "dl": "CAT2",
          "sub_impact": "Not Applicable",
          "checked": false,
          "comments": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book."
        }
      ]
    },
    {
      "id": 3,
      "first_name": "Male",
      "last_name": "Record Another",
      "email": "male.recordanother@gmail.com",
      "gender": "Male",
      "dob": "31-10-2017",
      "impact": "Applicable",
      "checked": false,
      "score": 25,
      "assigned_to": [
        {
          "co_score": 100,
          "dl": "CAT3",
          "sub_impact": "Applicable",
          "checked": false,
          "comments": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book."
        },
        {
          "co_score": 2,
          "dl": "CAT2",
          "sub_impact": "Not Applicable",
          "checked": false,
          "comments": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book."
        },
        {
          "co_score": 48,
          "dl": "CAT2",
          "sub_impact": "Not Applicable",
          "checked": false,
          "comments": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book."
        }
      ]
    },
    {
      "first_name": "Male",
      "last_name": "One More Record",
      "email": "male.onemorerecord@gmail.com",
      "gender": "Male",
      "dob": "08-08-1984",
      "impact": "Applicable",
      "id": 6,
      "checked": false,
      "score": "Updated",
      "assigned_to": [
        {
          "co_score": 4,
          "dl": "CAT1",
          "sub_impact": "Applicable",
          "checked": false,
          "comments": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book."
        },
        {
          "co_score": 85,
          "dl": "CAT3",
          "sub_impact": "Not Applicable",
          "checked": false,
          "comments": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book."
        }
      ]
    },
    {
      "first_name": "Female",
      "last_name": "Another Record",
      "email": "female.anotherrecord@gmail.com",
      "gender": "Female",
      "dob": "2000-07-15",
      "impact": "Applicable",
      "id": 7,
      "checked": false,
      "score": 85,
      "assigned_to": [
        {
          "co_score": 34,
          "dl": "CAT3",
          "sub_impact": "Applicable",
          "checked": false,
          "comments": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book."
        },
        {
          "co_score": 55,
          "dl": "CAT2",
          "sub_impact": "Not Applicable",
          "checked": false,
          "comments": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book."
        }
      ]
    },
    {
      "id": 8,
      "first_name": "New",
      "last_name": "Record",
      "email": "new.record@gmail.com",
      "gender": "Male",
      "dob": "2020-12-17",
      "impact": "Not Applicable",
      "score": 60,
      "checked": false,
      "assigned_to": [
        {
          "co_score": 94,
          "dl": "CAT1",
          "sub_impact": "Not Applicable",
          "checked": false,
          "comments": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book."
        },
        {
          "co_score": 85,
          "dl": "CAT3",
          "sub_impact": "Applicable",
          "checked": false,
          "comments": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book."
        }
      ]
    }
  ]
}

解决方案

There are a lot of ways to implement this, one way is something like:

in your template:

<tr *ngFor="let assignee of userObj.assigned_to">
    <td><input type="checkbox" [(ngModel)]="assignee.checked"></td>
    <td>{{assignee.sub_impact}}</td>
</tr>

and in your component:

updateUser() {
    this.isView = !this.isView;
    this.isEdit = !this.isEdit;
    this.userObj.impact = this.currentImpact;

    debugger;
    const checkedItems = this.userObj.assigned_to.filter(a => a.checked);
    checkedItems.forEach(a => {
      a.sub_impact = this.currentImpact;
      delete a.checked;
    });

    console.log("update");
    //this.commonService.updateUser().subscribe(response => {
    this.getCounts();
    //});
  }

notice that if you want different values between the user obj and the assigned_to you will have to create a new dropdown

here is a working stackblitz

这篇关于如何使batchEdit也可用于json嵌套节点?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆