鉴于此处的表格,我希望能够更新SQL表中的数据。为了创建实现此目的所需的SQL查询,我必须同时传递上一行的值和新行的值以进行适当的比较。
SQL更新语句示例:
UPDATE MyTable
SET column1 = new_value1, column2 = new_value2,
WHERE column1 = oldValue1 AND column2 = oldValue2
但是,由于我的输入使用双向绑定,因此在尝试将新值传递给SQL服务时,总是会得到新值。在发送更新之前,是否可以访问该行的先前值?
表单HTML:
<form #updateRowForm="ngForm" class="update-row-form">
<table mdbTable #tableEl="mdbTable" class="table table-bordered
table-responsive-md table-striped text-center">
<thead>
<tr>
<th *ngFor="let head of loadedTableData[0] | keys;">{{head}}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of loadedTableData; let i = index;">
<td *ngFor="let property of item | keys;"
class="form-group" #editRow>
<input #editRowProp mdbInput
[(ngModel)]="loadedTableData[i][property]"
(click)="updateValue(item)"
(ngModelChange)="changeValue($event, item)"
class="form-control"
[name]="property + '_' + i"
type="text">
</td>
<td>
<button type="button" mdbBtn class="btn btn-primary
rounded
btn-sm my-0"
(click)="updateRow(loadedTableData[i], item)">Update</button>
<hr>
<button type="button" mdbBtn class="btn btn-danger
rounded
btn-sm my-0" (click)="deleteRow(item)">Remove</button>
</td>
</tr>
</tbody>
</table>
</form>
组件TS文件:
import { Component, OnInit, ViewChild, ViewChildren, QueryList, OnDestroy } from
'@angular/core';
import { SqlService } from '../services/sql.service';
import { MdbTablePaginationComponent, MdbTableDirective } from 'angular-bootstrap-md';
import { NgForm, FormGroup } from '@angular/forms';
import { Subscription, BehaviorSubject } from 'rxjs';
import { MatSnackBar } from '@angular/material';
import { SuccessComponent } from '../snackbar/success/success.component';
import { ErrorComponent } from '../snackbar/error/error.component';
import { ConfirmComponent } from '../snackbar/confirm/confirm.component';
@Component({
selector: 'app-data-table',
templateUrl: './data-table.component.html',
styleUrls: ['./data-table.component.scss']
})
export class DataTableComponent implements OnInit, OnDestroy {
@ViewChild(MdbTablePaginationComponent) mdbTablePagination:
MdbTablePaginationComponent;
@ViewChild(MdbTableDirective) mdbTable: MdbTableDirective;
@ViewChild('addRowForm') addRowForm: NgForm;
@ViewChildren('prop') addRowProps: QueryList<any>;
@ViewChild('editRowForm') editRowForm: NgForm;
@ViewChild('editRow') editRow: FormGroup;
public loadedTableData: any = [];
public previousTableData: any = [];
public displayedColumns: any = [];
public tableHasBeenLoaded = false;
public rowBeingEdited: BehaviorSubject<any> = new BehaviorSubject<any>({});
public rowPreviousValue: BehaviorSubject<any> = new BehaviorSubject<any>({});
public currentTableData: any = {};
public rowsAffected = 0;
public elements: string[] = [];
public previous: any;
private subscriptions: Subscription[] = [];
constructor(private sqlService: SqlService,
private snackBar: MatSnackBar) { }
public ngOnInit(): void {
this.subscriptions.push(
this.sqlService.tableHasBeenLoaded.subscribe(data => {
this.tableHasBeenLoaded = data;
}),
this.sqlService.tableHasBeenLoaded.subscribe(data => {
this.tableHasBeenLoaded = data;
}),
this.sqlService.currentTableData.subscribe(data => {
this.currentTableData = data;
}),
this.sqlService.rowsAffected.subscribe(data => {
this.rowsAffected = data;
})
);
}
public updateRow(newRowValue: any, previousRowValue: any): void {
// Both of these values are the same.
console.log(newRowValue, ' << initialRow');
console.log(previousRowValue, ' <<previousRowVal')
const updateData = {
previousRowValue,
newRowValue
};
this.subscriptions.push(
this.sqlService.updateTableData(updateData)
.subscribe((resp) => {
console.log(resp, ' << update response');
// this.sqlService.currentDataView.next(resp);
if (resp) {
this.snackBar.openFromComponent(ConfirmComponent, {
duration: 3000,
data: this.rowsAffected
});
}
})
);
}
public ngOnDestroy(): void {
for (const sub of this.subscriptions) {
sub.unsubscribe();
}
}
}
SQL服务TS:
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { tap } from 'rxjs/operators';
import { Observable, BehaviorSubject } from 'rxjs';
import { ITableList } from '../interfaces/ITableList.interface';
@Injectable({
providedIn: 'root'
})
export class SqlService {
private uri = 'http://localhost:8080';
private headers = new HttpHeaders({ 'Content-Type': 'application/json; charset=utf-8' });
public currentDataView: BehaviorSubject<any> = new BehaviorSubject<any>([]);
public currentTableData: BehaviorSubject<any> = new BehaviorSubject<any>({});
public tableHasBeenLoaded: BehaviorSubject<any> = new BehaviorSubject<boolean>(false);
public rowsAffected: BehaviorSubject<number> = new BehaviorSubject<number>(0);
constructor(private http: HttpClient) { }
public updateTableData(updateData: any): Observable<any> {
const parsedData = JSON.parse(JSON.stringify(updateData));
if (updateData) {
return this.http.post(`${this.uri}/api/updateTableData`, parsedData).pipe(
tap(
response => {
this.rowsAffected.next(response.rowsAffected);
},
error => {
throw new Error(error);
}
)
);
}
}
}
答案 0 :(得分:1)
再创建一个对象(例如prevValue),在其中存储值。该值应该是Deepcopy而不是浅表复制。请使用JSON.stringify和JSON.parse在对象中复制值。 例如,在newValue对象中存储新值,然后再分配新值,将newValue保存在prevValue中,这样您将拥有prevValue, 例如,如果您想要第一个值而不是不更新preValue