Как получить доступ к предыдущему значению из двухстороннего элемента управления вводом формы?

Учитывая форму здесь, я хотел бы иметь возможность обновлять данные в таблице 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();
    }
  }

}

TS службы SQL:

    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);
            }
            )
        );
        }
    }

  }

person Adan    schedule 14.06.2019    source источник
comment
Я запутался... зачем вам предыдущее значение? Разве новые данные не должны просто заменить предыдущие данные?   -  person ViqMontana    schedule 15.06.2019
comment
@Viqas Для операторов SQL действие «Обновить» требует условия, в моем случае мне нужно было бы сравнить предыдущее значение строки (чтобы я мог ссылаться на него в базе данных) с новым значением. Например) UPDATE MyTable SET столбец1 = новое_значение1, столбец2 = новое_значение2, ... ГДЕ столбец1 = староезначение1; И столбец2 = староезначение2;   -  person Adan    schedule 17.06.2019
comment
Не могли бы вы просто использовать первичный ключ (возможно, id) для ссылки на запись, которую вы хотите обновить. Вот как вы должны это делать.   -  person ViqMontana    schedule 17.06.2019
comment
@Viqas Я понимаю, что вы говорите, но, учитывая мою таблицу SQL с 2 столбцами, столбец A представляет собой ввод из 2 символов, а столбец B представляет собой описание из 45 varchar, я не верю, что у меня есть доступ к UUID, если он не существует встроенный в SQL-сервер, о котором я не знаю? (Я все еще новичок в SQL и SQL Server)   -  person Adan    schedule 17.06.2019


Ответы (1)


привет, создайте еще один объект (например, prevValue), храните в нем значение. Это должно быть глубокое копирование, а не поверхностное копирование. Используйте JSON.stringify и JSON.parse для копирования значения в объект. например, в объекте newValue вы сохраняете новое значение, прежде чем назначать новое значение, сохраните newValue в prevValue, благодаря этому у вас будет prevValue, например, если вы хотите первое значение, чем не обновлять preValue

person Shahid Islam    schedule 15.06.2019
comment
Спасибо, сэр! Это то, что мне нужно было сделать. Создав глубокую копию, я мог сохранить как старое значение, так и новое значение для отправки на мой SQL-сервер для сравнения обновлений. - person Adan; 17.06.2019