问题
I am using angular httpclient to do the crud operations. I have an edit option for every record but I wanted to update multiple records at a time by selecting the checkbox and click on the update button.
Can you please look into it and help me to achieve the same to have a checkbox before impact for every row and select click on the edit button, select updated option n click on update button to update all those selected records.
Also, If I can get the count of how many applicable, not applicable, and FYI out of those records that would be really helpful.
common.service.ts
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 = '';
isNonTrade: boolean = false
checkAllNonTrades: boolean = false
changeTradesByCategory(event) {
if (event.target.name == 'nontrades') {
this.isNonTrade = true
}
if (this.isNonTrade && this.checkAllNonTrades) {
event.target.checked = true
}
}
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;
}
selectAllClicked(event) {
this.isBatchEdit = true;
const checked = event.target.checked;
this.allUser.forEach(item => item.selected = checked);
this.batchUpdateUsers = checked;
this.isBatchEdit = checked > 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(user).subscribe(() => {
this.getLatestUser();
})
}
});
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 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="chart--horiz">
<li class="chart__bar" [style.width]="impactCount.applicable * 10 + '%'"></li>
<li class="chart__bar" [style.width]="impactCount.notapplicable * 10 + '%'"></li>
<li class="chart__bar" [style.width]="impactCount.fyi * 10 + '%'"></li>
</ul>
</div>
</div>
</div>
<table class="table table-sm table-responsive">
<thead>
<tr>
<th>
<input type="checkbox" name="allNonTrades" (change)="selectAllClicked($event)">
</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 | paginate: { id: 'listing_pagination', itemsPerPage: 10, currentPage: page, totalItems: totalRecords }">
<td><input *ngIf="!isEdit" name="nontrades" [checked]="user.selected" (change)="changeTradesByCategory($event)" [(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.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>
<pagination-controls id="listing_pagination" directionLinks="true" (pageChange)="page = $event"></pagination-controls>
<div *ngIf="isView" class="view-details">
<ul>
<li>First Name <br />{{userObj.first_name}}</li>
<li>Last Name <br />{{userObj.last_name}}</li>
<li>Email <br />{{userObj.email}}</li>
<li>Gender <br />{{userObj.gender}}</li>
<li>IP Address <br />{{userObj.ip_address}}</li>
<li>Impact <br />{{userObj.impact}}</li>
</ul>
</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 *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> -->
</div>
db.json
{
"users": [
{
"id": 1,
"first_name": "Kunal",
"last_name": "Vijan",
"email": "vijan87@gmail.com",
"gender": "Male",
"ip_address": "1.1.1.1",
"impact": "Applicable"
},
{
"id": 2,
"first_name": "Kunal",
"last_name": "Vijan",
"email": "vijan87@gmail.com",
"gender": "Male",
"ip_address": "1.1.1.1",
"impact": "Not Applicable"
},
{
"id": 3,
"first_name": "Kunal",
"last_name": "Vijan",
"email": "vijan87@gmail.com",
"gender": "Male",
"ip_address": "1.1.1.1",
"impact": "FYI"
}
]
}
回答1:
The problem is in your batch update function. You populate the batchUpdateUserList
but then you send the this.userObj
to the server. The this.userObj
is a single record and is not going to give you the batch update you want.
batchUpdateUser() {
this.isBatchEdit = false;
const batchUpdateUserList = []; // objects to
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();
});
}
I had a comment in the function that was saying you need to create a new this.commonService.batchUpdate()
call for the server, but if is not possible to create a new call that sends a list of users for update, then you can do the following
batchUpdateUser() {
this.isBatchEdit = false;
const batchUpdateUserList = []; // objects to
this.allUser.forEach(user => {
if (user.checked) {
user.impact = this.currentImpact
batchUpdateUserList.push(user);
user.checked = false;
this.commonService.updateUser(user).subscribe();
}
});
this.getLatestUser();
}
but it is not recommended because this is going to be slow and buggy for large updates. You can use a forkJoin
to solve this issue, but it would prefered if you would create a new service that sends a list to the server for update. You can look at the stackblitz for the example but I didn't update it with this code because the project isn't connected to a server.
来源:https://stackoverflow.com/questions/65214192/how-do-i-add-functionality-to-update-multiple-records-at-a-time-to-json-from-ang