简体   繁体   English

如何将 angular 材质对话框的数据传递给父组件?

[英]how to pass data from angular material dialog to parent component?

I'm using angular 6 and I have a button which opens a dialog.我正在使用 angular 6 并且我有一个可以打开对话框的按钮。 in my dialog, I have a form that gets user's data and then I have two buttons to submit and cancel.在我的对话框中,我有一个获取用户数据的表单,然后我有两个按钮可以提交和取消。 I tried to show my form's data in the console but it returns undefined?我试图在控制台中显示我的表单数据,但它返回未定义? whats the problem: here is part of codes:问题是什么:这是代码的一部分:

main.component.ts: main.component.ts:

import { Work } from '../../../../classes/work_shift';
import { DialogContentComponent} from './dialog-content/dialog-content.component';
export class WorkShiftsComponent implements OnInit {
 shifts: Work[];
  name: string;
  start: string;
  end: string;
  constructor(public dialog: MatDialog, private shiftService: WorkShiftsService) { }

  ngOnInit() {
  }

  openDialog() {
    const dialogRef = this.dialog.open(DialogContentComponent, {
      width: '640px',
      disableClose: true,
      data: {name: this.name, start: this.start, end: this.end}
    });
    dialogRef.afterClosed().subscribe(result => {
      console.log('The dialog was closed');
      console.log(result);//returns undefined
    });
  }
}

dialogContent.component.html: dialogContent.component.html:

    <mat-dialog-content>
  <form class="example-form">
    <div fxLayout="column" fxLayoutAlign="space-around" class="form">
      <div class="input">
        <mat-form-field class="input4">
          <input matInput placeholder="Shift name">
        </mat-form-field>
      </div>
      <div>
        <mat-form-field class="input input2">
          <input matInput placeholder="Start" atp-time-picker>
        </mat-form-field>
        <mat-form-field class="input input2">
          <input matInput placeholder="End" atp-time-picker >
        </mat-form-field>
      </div>
      <br/>
    </div>
  </form>
</mat-dialog-content>
<mat-dialog-actions>
  <button class="mat-button" mat-button (click)="onClose()">Cancel</button>
  <button class="mat-button" mat-button [mat-dialog-close]="data" cdkFocusInitial color="primary">Create</button>
</mat-dialog-actions>

Check full Tutorial Link检查完整的教程链接

Just pass data back from Dialog component to parent in close() method只需在close()方法中将数据从 Dialog 组件传递回父组件

在此处输入图片说明

//dialog-box.component.ts
import { Component, Inject, Optional } from '@angular/core';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';

export interface UsersData {
  name: string;
  id: number;
}


@Component({
  selector: 'app-dialog-box',
  templateUrl: './dialog-box.component.html',
  styleUrls: ['./dialog-box.component.css']
})
export class DialogBoxComponent {

  action:string;
  local_data:any;

  constructor(
    public dialogRef: MatDialogRef<DialogBoxComponent>,
    //@Optional() is used to prevent error if no data is passed
    @Optional() @Inject(MAT_DIALOG_DATA) public data: UsersData) {
    console.log(data);
    this.local_data = {...data};
    this.action = this.local_data.action;
  }

  doAction(){
    this.dialogRef.close({event:this.action,data:this.local_data});
  }

  closeDialog(){
    this.dialogRef.close({event:'Cancel'});
  }

}

Then get event & data objects/values in parent component back然后取回父组件中的事件和数据对象/值

//app.component.ts
import { Component, ViewChild } from '@angular/core';

import { MatDialog, MatTable } from '@angular/material';
import { DialogBoxComponent } from './dialog-box/dialog-box.component';

export interface UsersData {
  name: string;
  id: number;
}

const ELEMENT_DATA: UsersData[] = [
  {id: 1560608769632, name: 'Artificial Intelligence'},
  {id: 1560608796014, name: 'Machine Learning'},
  {id: 1560608787815, name: 'Robotic Process Automation'},
  {id: 1560608805101, name: 'Blockchain'}
];
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  displayedColumns: string[] = ['id', 'name', 'action'];
  dataSource = ELEMENT_DATA;

  @ViewChild(MatTable,{static:true}) table: MatTable<any>;

  constructor(public dialog: MatDialog) {}

  openDialog(action,obj) {
    obj.action = action;
    const dialogRef = this.dialog.open(DialogBoxComponent, {
      width: '250px',
      data:obj
    });

    dialogRef.afterClosed().subscribe(result => {
      if(result.event == 'Add'){
        this.addRowData(result.data);
      }else if(result.event == 'Update'){
        this.updateRowData(result.data);
      }else if(result.event == 'Delete'){
        this.deleteRowData(result.data);
      }
    });
  }

  addRowData(row_obj){
    var d = new Date();
    this.dataSource.push({
      id:d.getTime(),
      name:row_obj.name
    });
    this.table.renderRows();

  }
  updateRowData(row_obj){
    this.dataSource = this.dataSource.filter((value,key)=>{
      if(value.id == row_obj.id){
        value.name = row_obj.name;
      }
      return true;
    });
  }
  deleteRowData(row_obj){
    this.dataSource = this.dataSource.filter((value,key)=>{
      return value.id != row_obj.id;
    });
  }


}

Data send to and/or receive from Dialog向 Dialog 发送和/或从 Dialog 接收数据

Dialog Component对话框组件

// HTML
<div [innerHTML]="data"></div>
<button (click)="cancel()">No</button>
<button (click)="confirm()">Yes</button>

// Typescript
export class DialogComponent {

  // receive data from parent using 'MAT_DIALOG_DATA'
  constructor(@Inject(MAT_DIALOG_DATA) public data: string,
    private dialogRef: MatDialogRef<DialogComponent>) { }

  cancel() {
    // closing itself and sending data to parent component
    this.dialogRef.close({ data: 'you cancelled' })
  }

  confirm() {
    // closing itself and sending data to parent component
    this.dialogRef.close({ data: 'you confirmed' })
  }

}

Parent Component父组件

constructor(private dialog: MatDialog) { }

// method to open dialog
openDialog() {
    let dialogRef = this.dialog.open(DialogComponent, {
      data: `Are you sure you want to delete?`
    })

    dialogRef.afterClosed().subscribe(res => {
      // received data from dialog-component
      console.log(res.data)
    })
}

DEMO COMMON POP-FORM演示常见的流行表格

common-pop-service:常见的流行服务:

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';

import { MatDialogRef, MatDialog, MatDialogConfig } from '@angular/material';
import { PupupFormComponent } from './pupup-form/pupup-form.component'

@Injectable()
export class CommonModelService {
  animal: string;
  name: string;
  date1: any;
  date2: any
  constructor(public dialog: MatDialog) { }
  openDialog(): Observable<any> {
    const dialogRef = this.dialog.open(PupupFormComponent, {
      width: '250px',
      data: { name: this.name, animal: this.animal, date1: this.date1, date2: this.date2 }
    });

    return dialogRef.afterClosed();
  }
}

parent.component.ts: parent.component.ts:

import { Component, Inject } from '@angular/core';
import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';

import { CommonModelService } from './common-model.service'

export interface DialogData {
  animal: string;
  name: string;
}

@Component({
  selector: 'dialog-overview-example',
  templateUrl: 'dialog-overview-example.html',
  styleUrls: ['dialog-overview-example.css'],
})
export class DialogOverviewExample {

  animal: string;
  name: string;

  constructor(private commModel: CommonModelService) { }

  openDialog() {
    this.commModel.openDialog().subscribe(data => {
      console.log(data);
    });
  }
}

parent.component.html: parent.component.html:

<button mat-raised-button (click)="openDialog()">Open Form</button>

pup-up-form.html: pup-up-form.html:

<div mat-dialog-content>
    <p>What's your favorite animal?</p>
    <mat-form-field>
        <input matInput [(ngModel)]="data.animal">
    </mat-form-field>

    <mat-form-field>
        <input matInput type="time" atp-time-picker [(ngModel)]="data.date1">
    </mat-form-field>

    <mat-form-field>
        <input matInput type="time" atp-time-picker [(ngModel)]="data.date2">
    </mat-form-field>
</div>

<div mat-dialog-actions>
    <button mat-button (click)="onNoClick()">No Thanks</button>
    <button mat-button [mat-dialog-close]="data" cdkFocusInitial>Ok</button>
</div>

I use EventEmitter than subscribe to save event of the dialog.我使用 EventEmitter 而不是订阅来保存对话框的事件。 A bit more work but fits better to solve my problem.更多的工作,但更适合解决我的问题。 Because mostly you pass an object which you modify in the Dlg and maybe you doesn't want to pass back the modification.因为大多数情况下您传递的是您在 Dlg 中修改的对象,并且您可能不想将修改传回。 The solution requere some kind of Deep Copy solution.该解决方案需要某种深度复制解决方案。

In the dialog:在对话框中:

import { EventEmitter } from '@angular/core';
@Component({...})
export class DlgComponent {
 data: any
 data: deepCopy(data) // some kindof deep copy solution like lodash
 onSave = new EventEmitter();

 ....
 save() {
     this.onSave.emit(this.data)
 }

In the parent component:在父组件中:

import { MatDialog, MatDialogConfig, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';

@Component({...})
export class ParentComponent {
 data: any
 
 constructor() {
   public dialogRef: MatDialogRef<DlgComponent>,
 }

 openDlg() {
   let dialogConfig = new MatDialogConfig(); 
   const dialogRef = this.dialog.open(DlgmComponent, dialogConfig);

   dialogRef.componentInstance.onSave.subscribe(data=> {
     this.data = data    
   })
 }
  
}

In the dialog:在对话框中:

close(): void {
   this.dialogRef.close(data); //on close pass data to parent
  }

In the parent component:在父组件中:

    openDialog(row){
        const dialogRef = this.dialog.open(DialogComponent, {
          width: '880px',
          height: '480px',
          disableClose: true,
          data: data
        });

        dialogRef.afterClosed().subscribe(res => {
        console.log("value from dialog",res) //data from dialog
            this.headerDialogValue = res;
            });
      } 

Below Solution works for me:下面的解决方案对我有用:

Matdialog Sharing Data Demo Matdialog分享资料Demo

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何将数据从对话框传递到 angular 中的父组件 - how to pass data from dialog to parent component in angular 如何将从 http 获取的数据从 Mat-Dialog 组件传递到 Angular 6 中的父组件? - How to pass data fetched from http, from a Mat-Dialog Component to a Parent component in angular 6? 如何将结果从 angular 8 材质对话框传递给其他组件? - How to pass result from angular 8 material dialog to other component? 如何将组件作为参数传递到“ Angular Material”对话框中? - How to pass a component as a parameter into an Angular Material dialog? Angular材料中Dialog组件和父组件中的数据映射 - Data Maping in Dialog component and parent component in Angular material 如何在Material 2对话框Angular 2中将数据从1个组件发送到其他组件 - How to send data in Material 2 dialog Angular 2 from 1 component to other 角度:将数据从“材质对话框”传递到组件,但未打开对话框 - Angular: Pass data from Material Dialog to component, which didn't open the dialog 如何将数据传递给角材料 2 的对话框 - How to pass data to dialog of angular material 2 角度材质对话框 - 将类型传递到对话框组件中 - Angular material dialog - pass types into dialog component 如何在Angular4中将数据从子组件传递到父组件 - How to pass data from child component to parent component in Angular4
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM