Значение углового впрыска также изменяет исходное значение (Диалог углового материала) - PullRequest
0 голосов
/ 01 февраля 2019

Я создал всплывающую форму для редактирования значений из таблицы, однако, как только я начинаю изменять данные в форме, они мгновенно изменяют исходные данные в таблице, когда я печатаю даже при открытом диалоговом окне.

Это мой основной компонент:

import { Version } from './../models/Version';
import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
import { AuthService } from '../services/auth.service';
import { ProjectsService } from '../services/projects.service';
import { ClientsService } from '../services/clients.service';
import { VersionsService } from '../services/versions.service';
import { Project } from '../models/Project';
import { EditprojectComponent } from './edit-project/editproject.component';
import {
  MatDialog,
  MatDialogRef,
  MAT_DIALOG_DATA,
  PageEvent,
  MatTableDataSource,
  MatPaginator
} from '@angular/material';
import { Client } from '../models/Client';

interface UIEntries {
  ProjectName: string;
  Client: string;
  Version: string;
  SOW: string;
  PM: string;
}

@Component({
  selector: 'app-projects',
  templateUrl: './projects.component.html',
  styleUrls: ['./projects.component.css']
})
export class ProjectsComponent implements OnInit {
  entries: UIEntries = {
    ProjectName: '',
    Client: '',
    Version: '',
    SOW: '',
    PM: ''
  };

  projects: Project[] = [];
  project: Project = new Project();
  loadingProjects: Boolean = true;
  clients: Client[];
  versions: Version[];

  length;
  pageSize = 5;
  pageSizeOptions: number[] = [5, 10, 25, 100];

  // MatPaginator Output
  pageEvent: PageEvent;
  dataSource;
  displayedColumns: string[] = ['Name', 'Client', 'SOW', 'PM', 'Version'];

  @ViewChild(MatPaginator) paginator: MatPaginator;

  setPageSizeOptions(setPageSizeOptionsInput: string) {
    this.pageSizeOptions = setPageSizeOptionsInput.split(',').map(str => +str);
  }

  constructor(
    private _auth: AuthService,
    private _clients: ClientsService,
    private _versions: VersionsService,
    private _projects: ProjectsService,
    public dialog: MatDialog
  ) {
    this._projects.getProjects().subscribe(res => {
      res.forEach(apiProject => {
        const tempProject = new Project();
        tempProject.populateProject(
          apiProject.Name,
          apiProject.ClientId,
          apiProject.VersionId,
          apiProject.Sow,
          apiProject.Pm,
          apiProject.CreatedBy
        );
        tempProject.ID = apiProject.Id;
        tempProject.Client = apiProject.Client;
        tempProject.Version = apiProject.Version;
        tempProject.Assignments = apiProject.Assignment;
        this.projects.push(tempProject);
      });
      this.length = this.projects.length;
      this.dataSource = new MatTableDataSource<Project>(this.projects);
      console.log(this.projects);
      this.dataSource.paginator = this.paginator;
      this.loadingProjects = false;
    });
  }

  ngOnInit(): void {
    this._clients.getClients().subscribe(res => {
      this.clients = res;
    });
    this._versions.getProjectVersions().subscribe(res => {
      this.versions = res;
    });
  }

  deleteProject(project: Project) {
    this._projects.deleteProject(project.ID).subscribe(res => {
      this.projects = [];
      this._projects.getProjects().subscribe(response => {
        response.forEach(apiProject => {
          const tempProject = new Project();
          tempProject.populateProject(
            apiProject.name,
            apiProject.clientId,
            apiProject.versionId,
            apiProject.sow,
            apiProject.pm,
            apiProject.createdBy
          );
          tempProject.ID = apiProject.id;
          this.projects.push(tempProject);
        });
        this.loadingProjects = false;
      });
    });
  }

  addProject() {
    this.project.Name = this.entries.ProjectName;
    this.project.VersionID = this.entries.Version;
    this.project.ClientID = this.entries.Client;
    this.project.SOW = this.entries.SOW;
    this.project.PM = this.entries.PM;
    this.project.CreatedBy = this._auth.user.UserID;
    this._projects.insertProject(this.project).subscribe(
      res => {
        this.projects.push(res);
      },
      err => console.log(err)
    );
  }

  editProject(project: Project) {
    const dialogRef = this.dialog.open(EditprojectComponent, {
      width: '400px',
      height: '450px',
      data: { project: project, clients: this.clients, versions: this.versions }
    });
  }
}
<div class="mainBody">
  <div class="leftBody">
    <h3>Add new project</h3>
    <div class="addproject-container mat-elevation-z1">
      <form (ngSubmit)="addProject()" class="form-container">
        <mat-form-field>
          <input
            [(ngModel)]="entries.ProjectName"
            name="ProjectName"
            matInput
            required
            placeholder="Project Name"/>
        </mat-form-field>
        <mat-form-field>
          <mat-select
            [(ngModel)]="entries.Client"
            required
            name="Client"
            placeholder="Client">
            <mat-option
              *ngFor="let client of clients; let i = index"
              [value]="client.Name">{{client.Name}}</mat-option>
          </mat-select>
        </mat-form-field>
        <mat-form-field>
          <mat-select
            [(ngModel)]="entries.Version"
            name="Version"
            required
            placeholder="Version">
            <mat-option
              *ngFor="let version of versions; let i = index"
              [value]="version.Description"
              >{{version.Description}}</mat-option>
          </mat-select>
        </mat-form-field>
        <mat-form-field>
          <input
            [(ngModel)]="entries.SOW"
            matInput
            name="SOW"
            required
            placeholder="SOW"
          />
        </mat-form-field>
        <mat-form-field>
          <input
            [(ngModel)]="entries.PM"
            matInput
            name="PM"
            required
            placeholder="PM"
          />
        </mat-form-field>
        <div class="button-container">
          <button mat-raised-button>Add Project</button>
        </div>
      </form>
    </div>
  </div>

  <div class="rightBody">
    <h3>Existing Projects</h3>
    <mat-spinner *ngIf="loadingProjects"></mat-spinner>
    <div class="listproject-container">
      <div *ngIf="!loadingProjects"  class="listproject-scrollcontainer mat-elevation-z1">
        <table  mat-table [dataSource]="dataSource">
          <ng-container matColumnDef="Name">
            <th mat-header-cell *matHeaderCellDef>Name</th>
            <td mat-cell *matCellDef="let element; let i = index;">
              <button mat-button (click)="editProject(projects[i])">{{element.Name}}</button></td>
          </ng-container>
          <ng-container matColumnDef="Client">
            <th mat-header-cell *matHeaderCellDef>Client</th>
            <td mat-cell *matCellDef="let element">
              {{element.Client.Name}}
            </td>
          </ng-container>
          <ng-container matColumnDef="SOW">
            <th mat-header-cell *matHeaderCellDef>SOW</th>
            <td mat-cell *matCellDef="let element">{{element.SOW}}</td>
          </ng-container>
          <ng-container matColumnDef="PM">
            <th mat-header-cell *matHeaderCellDef>PM</th>
            <td mat-cell *matCellDef="let element">{{element.PM}}</td>
          </ng-container>
          <ng-container matColumnDef="Version">
            <th mat-header-cell *matHeaderCellDef>Version</th>
            <td mat-cell *matCellDef="let element">{{element.Version.Description}}</td>
          </ng-container>
          <tr
            mat-header-row
            *matHeaderRowDef="displayedColumns; sticky: true"
          ></tr>
          <tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
        </table>
      </div>
      <mat-paginator #paginatorPlaceholder
        [length]="length"
        [pageSize]="pageSize"
        [pageSizeOptions]="pageSizeOptions"
        (page)="pageEvent = $event"
      >
      </mat-paginator>
    </div>
  </div>
</div>

И это компонент Dialog PopUp:

import { Component, OnInit, Inject } from '@angular/core';
import { Project } from 'src/app/models/Project';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';

@Component({
  selector: 'app-editproject',
  templateUrl: './editproject.component.html',
  styleUrls: ['./editproject.component.css']
})
export class EditprojectComponent implements OnInit {

  popupProject: Project = new Project();
  clients: any;
  versions: any;

  constructor(
    public dialogRef: MatDialogRef<{EditprojectComponent: any}>,
    @Inject(MAT_DIALOG_DATA) public data: any) {
    this.popupProject = data.project;
    this.clients = data.clients;
    this.versions = data.versions;
    console.log(this.popupProject);
  }

  onNoClick(): void {
    this.dialogRef.close();
  }

  ngOnInit() {
  }

  submitEdit() {

  }
}
<div  mat-dialog-content>
<form (ngSubmit)="submitEdit()" class="form-container">
  <mat-form-field>
    <input [(ngModel)]="popupProject.Name" name="ProjectName" matInput required placeholder="Project Name">
  </mat-form-field>
  <mat-form-field>
    <mat-select [(ngModel)]="popupProject.Client.Name" required name="Client" placeholder="Client">
      <mat-option *ngFor="let client of clients; let i=index" [value]="client.Name">{{client.Name}}</mat-option>
    </mat-select>
  </mat-form-field>
  <mat-form-field>
    <mat-select [(ngModel)]="popupProject.Version.Description" name="Version" required placeholder="Version">
      <mat-option *ngFor="let version of versions; let i=index" [value]="version.Description">{{version.Description}}</mat-option>
    </mat-select>
  </mat-form-field>
  <mat-form-field>
    <input [(ngModel)]="popupProject.SOW" matInput name="SOW" required placeholder="SOW">
  </mat-form-field>
  <mat-form-field>
    <input [(ngModel)]="popupProject.PM" matInput name="PM" required placeholder="PM">
  </mat-form-field>
  <div class="button-container">
    <button mat-raised-button [mat-dialog-close]="popupProject" cdkFocusInitial>Save</button>
  </div>
</form>
</div>

Я хочу добиться, чтобы форма во всплывающем окне была просто копией, если значение таблицы, и сохраняла ее только после нажатия кнопки сохранения.

1 Ответ

0 голосов
/ 02 февраля 2019

Когда вы передаете объекты в диалоговое окно как данные, эти объекты будут доступны для редактирования и изменения в диалоговом окне.Вы передали в свой диалог объект проекта, используемый в таблице, и все поля вашего диалога привязаны к этому объекту, поэтому изменения этих полей влияют на исходный объект проекта.Вы должны передать копию проекта:

editProject(project: Project) {
  const dialogRef = this.dialog.open(EditprojectComponent, {
    width: '400px',
    height: '450px',
    data: { 
      project: {
        Name: project.Name,
        Client: project.Client,
        ...
      }, 
      clients: this.clients, 
      versions: this.versions 
    }
  });
}

Возможно, вам понадобится быть более тщательным и, возможно, потребуется сделать глубокую копию объекта.Было бы проще и, вероятно, безопаснее передать только значения элементов объекта, которые вам нужны в диалоге, а не весь объект проекта.Это тоже может быть намного проще.

И затем, конечно, когда диалог «сохранен», вам нужно обновить исходный объект проекта, передав данные из диалога в ваш обработчик dialogRef.afterClosed ().(который вы не показали).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...