【问题标题】:Batch operations on restapi from angular从角度对rest api进行批量操作
【发布时间】:2020-12-11 05:03:52
【问题描述】:

我想使用 httpclient 从角度对我的 JSON 进行批量操作。但是当我这样做时,它无法更新 JSON,而只是更新最后检查的记录。

需要您的支持来修复代码。

我想我需要在服务中编写一个类似于 updateUser 的批量操作,携带多条记录并发布到服务。

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})

export class CommonService {

  constructor(private http:HttpClient) { }

  createUser(user: any) {
    return this.http.post("http://localhost:3000/users", user);
  }

  getAllUser() {
    return this.http.get("http://localhost:3000/users");
  }

  updateUser(user: any): Observable<any> {
    return this.http.put("http://localhost:3000/users/" + user.id, user);
  }

  deleteUser(user: any) {
    return this.http.delete("http://localhost:3000/users/" + user.id);
  }

}

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;
  totalRecords: any;
  page: Number = 1;
  currentImpact: string = '';

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

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

  batchUpdateUsers = [];

  constructor(private commonService: CommonService) {}

  ngOnInit() {
    this.getLatestUser();
  }
  
  checkboxClicked() {
    this.batchUpdateUsers = this.allUser.filter(row => row.checked);
    this.isView  = false;
    this.isBatchEdit = this.batchUpdateUsers.length > 0;
    this.currentImpact = this.userObj.impact;
  }

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

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

  getApplicableCounts() {
    this.impactCount = {applicable: 0,notapplicable: 0,fyi: 0}
    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++;
      }
    });
  }

  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 => {user.checked = false});
  }

  batchUpdateUser() {
    this.isBatchEdit = false;
    const batchUpdateUserList = [];
    this.allUser.forEach(user => {
      if (user.checked) {
        user.impact = this.currentImpact
        batchUpdateUserList.push(user);
        user.checked = false;
      }
    });

    this.commonService.updateUser(this.userObj).subscribe(() => {
      this.getLatestUser();
    })

    this.getApplicableCounts();
  }

}

app.component.html

<div class="container-fluid">
    <div class="text-right toal-records">Total: {{totalRecords}}</div>
      <div style="padding-left: 20px">
        Male: {{genderCount.male}} 
        Female: {{genderCount.female}}
        Other: {{genderCount.other}}</div>
      <div style="padding-left: 20px">
        Applicable: {{impactCount.applicable}}
        Not Applicable: {{impactCount.notApplicable}}
        FYI: {{impactCount.fyi}}
      </div>
      <table class="table table-sm table-responsive">
        <thead>
          <tr>
            <th *ngIf="!isEdit">Edit</th>
            <th>First Name</th>
            <th>Last Name</th>
            <th>Email</th>
            <th>Gender</th>
            <th>ID Address</th>
    <th>Impact</th>  
    <th></th>
  </tr>
</thead>
<tbody>
  <tr class="record-row" (click)="viewUser(user)" *ngFor="let user of allUser">
    <input *ngIf="!isEdit" [(ngModel)]="user.checked" type="checkbox" (change)="checkboxClicked()">
    <td>{{user.first_name}}</td>
    <td>{{user.last_name}}</td>
    <td>{{user.email}}</td>
    <td>{{user.gender}}</td>
    <td>{{user.ip_address}}</td>
    <td>{{user.impact}}</td>
    <td>
      <button *ngIf="!isEdit" class="btn btn-primary btn-sm" (click)="editUser(user)" data-toggle="modal" data-target="#exampleModel">Edit</button>
    </td>
  </tr>
</tbody>
</table>

<div *ngIf="isView" class="view-details">
  <ul>
    <li>First Name: {{userObj.first_name}}</li>
    <li>Last Name: {{userObj.last_name}}</li>
    <li>Email: {{userObj.email}}</li>
    <li>Gender: {{userObj.gender}}</li>
    <li>IP Address: {{userObj.ip_address}}</li>
    <li>Impact: {{userObj.impact}}</li>
  </ul>
</div>

<div *ngIf="isBatchEdit && !isEdit">    
<form #myForm="ngForm">
      <div class="form-group">
    <select name="impact" class="form-control form-control-sm" [(ngModel)]="currentImpact">
      <option>Applicable</option>
      <option>Not Applicable</option>
      <option>FYI</option>
    </select>
  </div>
  <button type="button" (click)="batchUpdateUser()" class="btn btn-success btn-sm btn-update mr-2">
    Update
    </button>
  <button type="button" (click)="cancelBatchEdit()" class="btn btn-secondary btn-sm">Cancel</button>
</form>        
  </div>

<div *ngIf="isEdit">    
<form #myForm="ngForm">
      <div class="form-group">
    <select name="impact" 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" >Update</button>
  <button type="button" (click)="cancelEdit()" class="btn btn-secondary btn-sm">Cancel</button>
</form>        
  </div>
</div>

https://stackblitz.com/edit/angular-ivy-bsrwmh?file=src/app/app.component.html

【问题讨论】:

  • 你想在这里完成什么? stackblitz 似乎运行良好

标签: json angular httpclient rest


【解决方案1】:

IIUC,你需要批量用户更新。这证实了在 API 端必须有一种方法可以一次更新多个用户。有了这个假设,这就是我的答案。

您可以在commonService 中添加此方法,然后传入您要更新的总用户列表。


  batchUpdateUsers(users: any[], batchSize = 10): Observable<void> {
    const batches = [];
    let offset = 0;
    while (offset < users.length) {
      batches.push(
        users.slice(offset, offset + batchSize)
      );
      offset += batchSize;
    }
    return forkJoin(
      batches.map(batch => this.http.put("http://localhost:3000/batchUserUpdate", batch))
    );
  }

注意:/batchUserUpdate ,必须有某种 API 可以接受多个用户更新。

如果你没有这样的batchUserUpdate api,你可以将return语句替换为以下,

return forkJoin(
  users.map(user => this.updateUser(user))
);

【讨论】:

  • 这对于全选选项是否相同?还是我需要添加一个新功能?
  • 就这个函数而言,您传入需要更新的用户的总列表。它可以是 selectAll 用户,或者只选择几个用户等......它应该可以工作。
  • faisd mpm 我如何创建选择所有功能 n 更新批处理用户?
  • 不确定我是否理解您的问题。此外,如果我的回答回答了原始问题,请将其标记为已接受的答案。此外,如果您有任何其他新问题,例如您要提出的问题。请发一个新的。谢谢。
  • 你能帮我解答这个问题吗stackoverflow.com/questions/65350436/…
猜你喜欢
  • 1970-01-01
  • 2018-02-14
  • 1970-01-01
  • 2019-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-24
相关资源
最近更新 更多