【问题标题】:How can I pass a service variable into an Angular Material dialog?如何将服务变量传递到 Angular Material 对话框?
【发布时间】:2016-11-17 06:40:04
【问题描述】:

对于mdDialog,如何传入变量?具体来说,如何将 Angular 服务注入到对话框组件中?

【问题讨论】:

    标签: angular angular-material angular-material2


    【解决方案1】:

    对于传递变量,您可以从 MdDialog.open() 方法调用中返回的 MdDialogRef 实例中获取对话框中打开的组件的实例。

    dialogRef = this.dialog.open(PizzaDialog, config)
    dialogRef.componentInstance.<property_name>
    

    修改后的披萨来自 github material2 docs angular material doc

    @Component({
      selector: 'pizza-component',
      template: `
      <button type="button" (click)="openDialog()">Open dialog</button>
      `
    })
    export class PizzaComponent {
    
      constructor(public dialog: MdDialog) { }
    
      openDialog() {
        let config = new MdDialogConfig();
        let dialogRef:MdDialogRef<PizzaDialog> = this.dialog.open(PizzaDialog, config);
        dialogRef.componentInstance.name = "Ham and Pineapple";
        dialogRef.componentInstance.size = "Large";
      }
    }
    
    @Component({
      selector: 'pizza-dialog',
      template: `
      <h2>{{name}}</h2>
      <p>Size: {{size}}</p>
      <button type="button" (click)="dialogRef.close('yes')">Yes</button>
      <button type="button" (click)="dialogRef.close('no')">No</button>
      `
    })
    export class PizzaDialog {
      name:string;
      size:string;
      constructor(public dialogRef: MdDialogRef<PizzaDialog>) { }
    }
    

    【讨论】:

    • 嗨,非常感谢!我刚刚使用最新的 Angular 版本尝试了您的解决方案,这一行出现编译错误: dialogRef:MdDialogRef = this.dialog.open(PizzaDialog, config);我这样修复它: let dialogRef: MdDialogRef = this.dialog.open(PizzaDialog, config);
    • 我认为ThiagoPXP(MdDialogConfig 数据对象)的答案非常好,是一种将数据传递到子组件然后在构造函数中设置子类变量的更好方法,见下文
    【解决方案2】:

    Material2 beta.2

    dialog.open() 函数采用第二个参数 config (MdDialogConfig),您可以在其中指定任何 data 对象。

    this.dialog.open(YourComponent, {
      data: {
        anyProperty: "myValue"
      }
    });
    

    然后,您可以从用于对话窗口的组件中检索此对象。

    export class YourDialogComponent {
    
      constructor(public dialogRef: MdDialogRef<YourComponent>) {
        console.log('data', this.dialogRef.config.data);
      }
    }
    

    更新:beta.3

    以上答案适用于 Material2 的 2.0.0-beta.2 版本。如果您使用的是2.0.0-beta.3,则config 属性已从MdDialogRef 中删除。您可以改为使用打开组件的MD_DIALOG_DATA 注入该值。

    新的导入语句

    import {MdDialog, MdDialogRef, MdDialogConfig, MD_DIALOG_DATA} from '@angular/material';
    

    打开对话框

    this.dialog.open(YourComponent, {
      data: {
        anyProperty: "myValue"
      }
    });
    

    DialogRef 组件中检索数据

    export class YourDialogComponent {
    
      constructor(
        public dialogRef: MdDialogRef<YourDialogComponent>,
        @Inject(MD_DIALOG_DATA) public data: any) {
    
        console.log('data', this.data);
      }
    }
    

    【讨论】:

    • 这看起来像是推荐的方式。但是为什么要优先使用 dialogRef.componentInstance 呢?
    • 在我看来,这是关于“关注点分离”。打开对话框的组件不应该知道对话框在内部是如何工作的。因此,它不应该直接设置任何对话框的属性。更可预测的是,对话框可以在其构造函数中使用所有必需的数据启动自身。
    • @ThiagoPXP : 是 beta3 意味着它是双向数据绑定吗?
    【解决方案3】:

    来自https://material.angular.io/components/dialog/overview上的官方文档

    与 Dialog 组件共享数据。

    如果您想与对话框共享数据,可以使用数据选项将信息传递给对话框组件。

    let dialogRef = dialog.open(YourDialog, {
      data: 'your data',
    });
    

    要访问对话框组件中的数据,您必须使用 MD_DIALOG_DATA 注入令牌:

    import {Component, Inject} from '@angular/core';
    import {MD_DIALOG_DATA} from '@angular/material';
    
    @Component({
      selector: 'your-dialog',
      template: 'passed in {{ data }}',
    })
    
    export class YourDialog {
      constructor(@Inject(MD_DIALOG_DATA) public data: any) { }
    }
    

    【讨论】:

    • 谢谢!但是使用 dialogRef.componentInstance 有什么缺点呢?
    【解决方案4】:

    我是这样做的。

    pizza.service.ts

    import { Injectable } from '@angular/core';
    
    @Injectable()
    export class PizzaService {
        getTopping(): string {
            return "Mushrooms"
        }
    }
    

    pizzaDialog.component.ts

    import { Component } from '@angular/core';
    import { MdDialogRef} from '@angular/material';
    import {PizzaService} from './pizza.service';
    
    @Component({
        selector: 'pizza-dialog',
        template: `{{pizzaTopping}}
        <button type="button" (click)="dialogRef.close('yes')">Yes</button>
        <button type="button" (click)="dialogRef.close('no')">No</button>
      `,
        providers: [PizzaService]
    })
    export class PizzaDialog {
        pizzaTopping: string;
    
        constructor(public dialogRef: MdDialogRef<PizzaDialog>, private pizzaService: PizzaService) { };
    
        ngOnInit(): void {
            this.pizzaTopping = this.pizzaService.getTopping()
        }
    }
    

    【讨论】:

    • 回答问题,-如何在对话中调用服务,谢谢,正是我想要的
    【解决方案5】:

    提供更新的答案以适应从“Md”到“Mat”的更新:

    • 这假设您已经成功实现了一个对话框,现在只是想添加一个输入
    • 这是当您遇到@angular/material 没有导出成员“MD_DIALOG_DATA”的问题时的解决方案

    要打开带有数据的对话框,请传入一个数据对象:

    this.dialog.open(YourComponent, {
      data: {
        anyProperty: "myValue"
      }
    });
    

    在对话框中检索该数据:

    import { Component, Inject } from '@angular/core';
    import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
    
    export class YourDialogComponent {
    
      constructor(
        public dialogRef: MatDialogRef<YourDialogComponent>,
        @Inject(MAT_DIALOG_DATA) public data: any) {
    
        console.log('data passed in is:', this.data);
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多