如何添加一次将多条记录从 angular 更新到 json 的功能
How do I add functionality to update multiple records at a time to json from angular
我正在使用 angular httpclient 进行 crud 操作。我对每条记录都有一个编辑选项,但我想通过 select 选中复选框并单击更新按钮来一次更新多条记录。
你能不能看看它并帮助我实现同样的效果,在每一行的影响之前都有一个复选框,然后 select 单击编辑按钮,select 更新选项 n 单击更新按钮更新所有这些 selected 记录。
此外,如果我能从这些记录中计算出有多少适用、不适用和仅供参考,那将非常有帮助。
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"
}
]
}
问题出在你的批量更新功能上。您填充 batchUpdateUserList
但随后将 this.userObj
发送到服务器。 this.userObj
是单个记录,不会为您提供所需的批量更新。
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();
});
}
我在函数中有一条评论说您需要为服务器创建一个新的 this.commonService.batchUpdate()
调用,但如果无法创建一个新的调用来发送用户列表以进行更新,那么您可以执行以下操作
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();
}
但不推荐这样做,因为这对于大型更新来说会很慢而且有问题。您可以使用 forkJoin
来解决这个问题,但如果您创建一个向服务器发送列表以进行更新的新服务,它会更受欢迎。您可以查看 stackblitz 示例,但我没有使用此代码更新它,因为该项目未连接到服务器。
我正在使用 angular httpclient 进行 crud 操作。我对每条记录都有一个编辑选项,但我想通过 select 选中复选框并单击更新按钮来一次更新多条记录。
你能不能看看它并帮助我实现同样的效果,在每一行的影响之前都有一个复选框,然后 select 单击编辑按钮,select 更新选项 n 单击更新按钮更新所有这些 selected 记录。
此外,如果我能从这些记录中计算出有多少适用、不适用和仅供参考,那将非常有帮助。
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"
}
]
}
问题出在你的批量更新功能上。您填充 batchUpdateUserList
但随后将 this.userObj
发送到服务器。 this.userObj
是单个记录,不会为您提供所需的批量更新。
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();
});
}
我在函数中有一条评论说您需要为服务器创建一个新的 this.commonService.batchUpdate()
调用,但如果无法创建一个新的调用来发送用户列表以进行更新,那么您可以执行以下操作
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();
}
但不推荐这样做,因为这对于大型更新来说会很慢而且有问题。您可以使用 forkJoin
来解决这个问题,但如果您创建一个向服务器发送列表以进行更新的新服务,它会更受欢迎。您可以查看 stackblitz 示例,但我没有使用此代码更新它,因为该项目未连接到服务器。