From ba4119b589813fe5c3f2e811b7abf207e3d949dd Mon Sep 17 00:00:00 2001 From: crisbeto Date: Sat, 21 Jan 2017 14:27:57 +0100 Subject: [PATCH] Switch to using an OpaqueToken. --- src/demo-app/dialog/dialog-demo.ts | 6 ++--- src/lib/dialog/README.md | 41 +++++++++++++++++------------- src/lib/dialog/dialog-config.ts | 7 +---- src/lib/dialog/dialog-injector.ts | 10 ++++---- src/lib/dialog/dialog.spec.ts | 17 +++++++++---- src/lib/dialog/dialog.ts | 2 +- src/lib/dialog/index.ts | 1 + 7 files changed, 46 insertions(+), 38 deletions(-) diff --git a/src/demo-app/dialog/dialog-demo.ts b/src/demo-app/dialog/dialog-demo.ts index c659a582f081..545680388824 100644 --- a/src/demo-app/dialog/dialog-demo.ts +++ b/src/demo-app/dialog/dialog-demo.ts @@ -1,5 +1,5 @@ -import {Component} from '@angular/core'; -import {MdDialog, MdDialogRef, MdDialogConfig, MdDialogData} from '@angular/material'; +import {Component, Inject} from '@angular/core'; +import {MdDialog, MdDialogRef, MdDialogConfig, MD_DIALOG_DATA} from '@angular/material'; @Component({ moduleId: module.id, @@ -55,7 +55,7 @@ export class DialogDemo { export class JazzDialog { constructor( public dialogRef: MdDialogRef, - public data: MdDialogData) { } + @Inject(MD_DIALOG_DATA) public data: any) { } } diff --git a/src/lib/dialog/README.md b/src/lib/dialog/README.md index 3bf45ee479ce..594548484bd2 100644 --- a/src/lib/dialog/README.md +++ b/src/lib/dialog/README.md @@ -15,7 +15,7 @@ MdDialog is a service, which opens dialogs components in the view. | --- | ------------ | | `role?: DialogRole = 'dialog'` | The ARIA role of the dialog element. Possible values are `dialog` and `alertdialog`. | | `disableClose?: boolean = false` | Whether to prevent the user from closing a dialog by clicking on the backdrop or pressing escape. | -| `data?: { [key: string]: any }` | Data that will be injected into the dialog as `MdDialogData`. | +| `data?: { [key: string]: any }` | Data that will be injected into the dialog as via the `MD_DIALOG_DATA` token. | | `width?: string = ''` | Width of the dialog. Takes any valid CSS value. | | `height?: string = ''` | Height of the dialog. Takes any valid CSS value. | | `position?: { top?: string, bottom?: string, left?: string, right?: string }` | Position of the dialog that overrides the default centering in it's axis. | @@ -70,23 +70,6 @@ export class PizzaComponent { }); } } - -@Component({ - selector: 'pizza-dialog', - template: ` -

Would you like to order a {{ data.pizzaType }} pizza?

- - - - - - ` -}) -export class PizzaDialog { - constructor( - public dialogRef: MdDialogRef, - public data: MdDialogData) { } -} ``` The dialog component should be declared in the list of entry components of the module: @@ -106,3 +89,25 @@ The dialog component should be declared in the list of entry components of the m export class AppModule { } ``` + +## Injecting data +If you want to pass in extra data to your dialog instance, you can do so +by using the `MD_DIALOG_DATA` injection token. +``` +@Component({ + selector: 'pizza-dialog', + template: ` +

Would you like to order a {{ data.pizzaType }} pizza?

+ + + + + + ` +}) +export class PizzaDialog { + constructor( + public dialogRef: MdDialogRef, + @Inject(MD_DIALOG_DATA) public data: any) { } +} +``` diff --git a/src/lib/dialog/dialog-config.ts b/src/lib/dialog/dialog-config.ts index 52e0a9786853..37337591776f 100644 --- a/src/lib/dialog/dialog-config.ts +++ b/src/lib/dialog/dialog-config.ts @@ -11,11 +11,6 @@ export interface DialogPosition { right?: string; }; -/** Data to be injected into a dialog. */ -export class MdDialogData { - [key: string]: any; -} - /** * Configuration for opening a modal dialog with the MdDialog service. */ @@ -38,7 +33,7 @@ export class MdDialogConfig { position?: DialogPosition; /** Data being injected into the child component. */ - data?: MdDialogData; + data?: any; // TODO(jelbourn): add configuration for lifecycle hooks, ARIA labelling. } diff --git a/src/lib/dialog/dialog-injector.ts b/src/lib/dialog/dialog-injector.ts index 839170524463..87f0d7ffdc91 100644 --- a/src/lib/dialog/dialog-injector.ts +++ b/src/lib/dialog/dialog-injector.ts @@ -1,21 +1,21 @@ -import {Injector} from '@angular/core'; +import {Injector, OpaqueToken} from '@angular/core'; import {MdDialogRef} from './dialog-ref'; -import {MdDialogData} from './dialog-config'; +export const MD_DIALOG_DATA = new OpaqueToken('MdDialogData'); /** Custom injector type specifically for instantiating components with a dialog. */ export class DialogInjector implements Injector { constructor( + private _parentInjector: Injector, private _dialogRef: MdDialogRef, - private _data: MdDialogData, - private _parentInjector: Injector) { } + private _data: any) { } get(token: any, notFoundValue?: any): any { if (token === MdDialogRef) { return this._dialogRef; } - if (token === MdDialogData && this._data) { + if (token === MD_DIALOG_DATA && this._data) { return this._data; } diff --git a/src/lib/dialog/dialog.spec.ts b/src/lib/dialog/dialog.spec.ts index 9c29db33a0cf..7193f393b42e 100644 --- a/src/lib/dialog/dialog.spec.ts +++ b/src/lib/dialog/dialog.spec.ts @@ -7,14 +7,21 @@ import { TestBed, tick, } from '@angular/core/testing'; +import {NgModule, + Component, + Directive, + ViewChild, + ViewContainerRef, + Injector, + Inject, +} from '@angular/core'; import {By} from '@angular/platform-browser'; -import {NgModule, Component, Directive, ViewChild, ViewContainerRef, Injector} from '@angular/core'; import {MdDialogModule} from './index'; import {MdDialog} from './dialog'; import {OverlayContainer} from '../core'; import {MdDialogRef} from './dialog-ref'; import {MdDialogContainer} from './dialog-container'; -import {MdDialogData} from './dialog-config'; +import {MD_DIALOG_DATA} from './dialog-injector'; describe('MdDialog', () => { @@ -254,8 +261,8 @@ describe('MdDialog', () => { let instance = dialog.open(DialogWithInjectedData, config).componentInstance; - expect(instance.data['stringParam']).toBe(config.data.stringParam); - expect(instance.data['dateParam']).toBe(config.data.dateParam); + expect(instance.data.stringParam).toBe(config.data.stringParam); + expect(instance.data.dateParam).toBe(config.data.dateParam); }); it('should throw if injected data is expected but none is passed', () => { @@ -502,7 +509,7 @@ class ComponentThatProvidesMdDialog { /** Simple component for testing ComponentPortal. */ @Component({template: ''}) class DialogWithInjectedData { - constructor(public data: MdDialogData) { } + constructor(@Inject(MD_DIALOG_DATA) public data: any) { } } // Create a real (non-test) NgModule as a workaround for diff --git a/src/lib/dialog/dialog.ts b/src/lib/dialog/dialog.ts index d6e4cd203576..9e9ac5dbd60e 100644 --- a/src/lib/dialog/dialog.ts +++ b/src/lib/dialog/dialog.ts @@ -120,7 +120,7 @@ export class MdDialog { // inject the MdDialogRef. This allows a component loaded inside of a dialog to close itself // and, optionally, to return a value. let userInjector = config && config.viewContainerRef && config.viewContainerRef.injector; - let dialogInjector = new DialogInjector(dialogRef, config.data, userInjector || this._injector); + let dialogInjector = new DialogInjector(userInjector || this._injector, dialogRef, config.data); let contentPortal = new ComponentPortal(component, null, dialogInjector); diff --git a/src/lib/dialog/index.ts b/src/lib/dialog/index.ts index e14bc904b78b..664f8e4b0ab5 100644 --- a/src/lib/dialog/index.ts +++ b/src/lib/dialog/index.ts @@ -57,3 +57,4 @@ export * from './dialog-container'; export * from './dialog-content-directives'; export * from './dialog-config'; export * from './dialog-ref'; +export {MD_DIALOG_DATA} from './dialog-injector';