Home > Enterprise >  When you change the value in the dialog box, the value in the main table changes
When you change the value in the dialog box, the value in the main table changes

Time:03-13

Project on Angularjs.

There is a table with data

<mat-card>
  <mat-card-content >
    <table  mat-table [dataSource]="dataQuiz">
      <!-- Name Column -->
      <ng-container matColumnDef="name" >
        <th  mat-header-cell *matHeaderCellDef > Name </th>
        <td  mat-cell *matCellDef="let element"> {{element.name}} </td>
      </ng-container>
    </table>
  </mat-card-content>
</mat-card>

from which I call the data editing dialog box

openEditDialog(quizDto: QuizDto) {
  const dialogRef = this.dialog.open(QuizEditDialogComponent, {
    data: [quizDto,
      'edit'
    ],
    width: '400px'
  });
}

template

<mat-dialog-content>
  <p mat-dialog-title>{{dialogTitle}}</p>
  <mat-form-field appearance="standard">
    <mat-label>Name</mat-label>
    <input
      matInput maxlength="100"
      [(ngModel)]="quizDto.name"
      (keydown.enter)="confirm()"
    />
  </mat-form-field>
</mat-dialog-content>

The problem is as follows. In the dialog box, I change the value of the "name" field. At the same time, the same field changes in the main table. It seems like everything is logical, a reference to one object, the connection is bidirectional. But this is wrong. How do I break this connection? I can't think of anything smarter than adding another variable

openEditDialog(quizDto: QuizDto) {
  const curQuiz = new QuizDto(quizDto.id, quizDto.name);
  const dialogRef = this.dialog.open(QuizEditDialogComponent, {
    data: [curQuiz ,
      'edit'
    ],
    width: '400px'
  });
}

But this code doesn't look very good. Maybe there is a more beautiful solution?

CodePudding user response:

As you note, if you are using two way binding with a shared object, any change to that object (by anyone) will immediately be reflected in the UI. You'll need to have a copy of the original object one way or another to allow the dialog to edit it without having changes reflected immediately in the UI.

Your proposed solution won't do you any good, because even though curQuiz and quizDto are different variables, they are references to the same object:

openEditDialog(quizDto: QuizDto) {
  const curQuiz = quizDto; // oops! these still refer to same object
  const dialogRef = this.dialog.open(QuizEditDialogComponent, {
    data: [curQuiz ,
      'edit'
    ],
    width: '400px'
  });
}

I would suggest providing the dialog with a copy of the object data it needs to do its job, and then having it return the updated data to you when it is closed. You can then update the original object, and therefore the UI.

openEditDialog(quizDto: QuizDto) {
  const props = {...quizDto}; // copy props (adjust as necessary)
  const dialogRef = this.dialog.open(QuizEditDialogComponent, {
    data: [props,'edit']
  });
  dialogRef.afterClosed().subscribe(result => {
    if (result) {
      quizDto.name = result.name;
      // ...
    }
}

Your dialog would then look something like:

export class QuizEditDialogComponent {
  // ...
  close() {
    this.dialogRef.close({ name: 'updated name here' );
  }

CodePudding user response:

you can use one way binding.

[ngModel]=quizDto.name
  • Related