首页 > 解决方案 > 无法在 Angular 材质的材质对话框中传递数据

问题描述

我正在尝试在 Angular Material 中传递两个字符串。Mat Dialog 内容中的 HTML 代码是创建 2 个 cdk 下拉列表,其中可以在数组之间交换值。

我为类似的问题经历了这个答案并尝试实施它,但它没有奏效。如何将数据传递给角度材料2的对话框

这是我的对话框类以及调用对话框类的类的代码。

export class TableComponent implements OnInit {
   displayedColumns: string[] = ['A', 'B', 'C'];
   availableColumns: string[] = [];

   openDialog() {
     const dialogRef = this.dialog.open(ColumnsDialog, {
     width: '500px',
     height: '500px',
     data: {
       displayedColumns: this.displayedColumns,
       availableColumns: this.availableColumns
     },
     });
   }  

  @Component({
  selector: 'columns-dialog',
  templateUrl: 'columns-dialog.html',
  changeDetection:ChangeDetectionStrategy.OnPush
 })

 export class ColumnsDialog {
   constructor(public dialogRef: MatDialogRef<ColumnsDialog>,
    @Inject(MAT_DIALOG_DATA) public data: any) {}

   onCloseClick(): void {
    this.dialogRef.close(true);
  }


 drop(event: CdkDragDrop<string[]>) {
   if (event.previousContainer === event.container) {
    moveItemInArray(event.container.data, event.previousIndex, 
    event.currentIndex);
   } else {
     transferArrayItem(event.previousContainer.data,
                    event.container.data,
                    event.previousIndex,
                    event.currentIndex);
   }
 } 
}

这是我的 mat-dialog 内容的代码。

<mat-dialog-content>
<div >
    <h2>Unselected Columns</h2>

                    <div
                      cdkDropList
                      #availableColumnsList="cdkDropList"
                      [cdkDropListData]="availableColumns"
                      [cdkDropListConnectedTo]="[displayedColumnsList]"

                      (cdkDropListDropped)="drop($event)">
                      <div  *ngFor="let item of availableColumns" cdkDrag>{{item}}</div>
                    </div>
                  </div>

                  <div >
                    <h2>Selected Columns</h2>

                    <div
                      cdkDropList
                      #displayedColumnsList="cdkDropList"
                      [cdkDropListData]="displayedColumns"
                      [cdkDropListConnectedTo]="[availableColumnsList]"

                      (cdkDropListDropped)="drop($event)">
                      <div *ngFor="let item of displayedColumns" cdkDrag>{{item}}</div>
                    </div>
                  </div>
 </mat-dialog-content>

当我传递displayedColumns 和availableColumns 字符串时,我想要2 个cdk 下拉列表,其中数组displayeColumns 的值可以传递给可用列,反之亦然。当我在单击该对话框正在打开时使用按钮的下拉菜单时,我能够实现这一点,因此我知道 cdk 下拉列表的代码有效。我认为问题在于将数据传递给 mat-dialog。

此外,我不希望 mat-dialog 为显示创建自己的显示列和可用列的副本,因为我正在使用这些字符串数组来更改 Angular 材料表的显示列。

标签: angularangular-material

解决方案


打开对话框时通过 MatDialogConfig 对象提供给对话框的对话框数据通常是“原始”数据的副本。因此,从对话框中所做的更改仅限于对话框。使用 MatDialog 修改“原始”数据的标准方法是通过 MatDialogRef 函数close()afterClosed().

close()应使用已更改的对话数据调用。你可以传递任何你想要的东西,但通常你传递你注入到对话框类或它的某些部分的数据对象:

this.dialogRef.close(this.data);

afterClosed()应该订阅,以便在关闭对话框时调用处理程序。处理程序接收传递给的数据close(),然后通常使用它来更新“原始”数据:

dialogRef.afterClosed().subscribe(result => {
  // do something with the result
});

处理程序只会在close()被调用时被触发。通常你的对话框会有一个关闭按钮。在对话框外单击或按退出键不是“关闭”操作(它是“取消”操作),因此不会(也不应该)调用处理程序。

您的代码不执行任何此操作。您有一个关闭对话框的函数,但它传递的值为“true”,而不是对话框数据,并且它永远不会在任何地方调用,因为您还没有实现对话框关闭的处理程序。

要解决此问题,请执行以下操作:

表格组件

displayedColumns: string[] = ['A', 'B', 'C'];
availableColumns: string[] = [];

openDialog() {
  const dialogRef = this.dialog.open(ColumnsDialog, {
    width: '500px',
    height: '500px',
    data: {
      displayedColumns: this.displayedColumns,
      availableColumns: this.availableColumns
    },
  });

  dialogRef.afterClosed().subscribe(result => {
    this.displayedColumns = result.displayedColumns,
    this.availableColumns = result.availableColumns
  });
}

列对话框

constructor(public dialogRef: MatDialogRef<ColumnsDialog>,
  @Inject(MAT_DIALOG_DATA) public data: any) {}

onCloseClick(): void {
  this.dialogRef.close(this.data);
}

当然,您还必须onCloseClick()从对话框上的按钮中使用该功能:

<div mat-dialog-actions>
    <button mat-button (click)="onCloseClick()">Update</button>
</div>

如果您愿意,您可以完全使用 HTML 来做到这一点,因此您不需要定义函数:

<div mat-dialog-actions>
    <button mat-button [mat-dialog-close]="data">Update</button>
</div>

推荐阅读