Skip to content

Commit be0da09

Browse files
devversionmmalerba
authored andcommitted
fix(dialog): use injector from viewContainerRef if provided (#2655)
* Right now the `MdDialog` always instantiates the user-provided component with the injector from the `MdDialog` service. This is not valid, because developers can provide the `viewContainerRef` to create their dialog in the desired component structure and also expect the parent injector to be the same as in the `viewContainerRef`.
1 parent c7d1c17 commit be0da09

File tree

2 files changed

+24
-5
lines changed

2 files changed

+24
-5
lines changed

src/lib/dialog/dialog.spec.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
tick,
99
} from '@angular/core/testing';
1010
import {By} from '@angular/platform-browser';
11-
import {NgModule, Component, Directive, ViewChild, ViewContainerRef} from '@angular/core';
11+
import {NgModule, Component, Directive, ViewChild, ViewContainerRef, Injector} from '@angular/core';
1212
import {MdDialogModule} from './index';
1313
import {MdDialog} from './dialog';
1414
import {OverlayContainer} from '../core';
@@ -64,6 +64,21 @@ describe('MdDialog', () => {
6464
expect(dialogContainerElement.getAttribute('role')).toBe('dialog');
6565
});
6666

67+
it('should use injector from viewContainerRef for DialogInjector', () => {
68+
let dialogRef = dialog.open(PizzaMsg, {
69+
viewContainerRef: testViewContainerRef
70+
});
71+
72+
viewContainerFixture.detectChanges();
73+
74+
let dialogInjector = dialogRef.componentInstance.dialogInjector;
75+
76+
expect(dialogRef.componentInstance.dialogRef).toBe(dialogRef);
77+
expect(dialogInjector.get(DirectiveWithViewContainer)).toBeTruthy(
78+
'Expected the dialog component to be created with the injector from the viewContainerRef.'
79+
);
80+
});
81+
6782
it('should open a dialog with a component and no ViewContainerRef', () => {
6883
let dialogRef = dialog.open(PizzaMsg);
6984

@@ -435,7 +450,8 @@ class ComponentWithChildViewContainer {
435450
/** Simple component for testing ComponentPortal. */
436451
@Component({template: '<p>Pizza</p> <input> <button>Close</button>'})
437452
class PizzaMsg {
438-
constructor(public dialogRef: MdDialogRef<PizzaMsg>) { }
453+
constructor(public dialogRef: MdDialogRef<PizzaMsg>,
454+
public dialogInjector: Injector) {}
439455
}
440456

441457
@Component({

src/lib/dialog/dialog.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ export class MdDialog {
4242

4343
let overlayRef = this._createOverlay(config);
4444
let dialogContainer = this._attachDialogContainer(overlayRef, config);
45-
let dialogRef = this._attachDialogContent(component, dialogContainer, overlayRef);
45+
let dialogRef = this._attachDialogContent(component, dialogContainer, overlayRef, config);
4646

4747
this._openDialogs.push(dialogRef);
4848
dialogRef.afterClosed().subscribe(() => this._removeOpenDialog(dialogRef));
@@ -96,12 +96,14 @@ export class MdDialog {
9696
* @param component The type of component being loaded into the dialog.
9797
* @param dialogContainer Reference to the wrapping MdDialogContainer.
9898
* @param overlayRef Reference to the overlay in which the dialog resides.
99+
* @param config The dialog configuration.
99100
* @returns A promise resolving to the MdDialogRef that should be returned to the user.
100101
*/
101102
private _attachDialogContent<T>(
102103
component: ComponentType<T>,
103104
dialogContainer: MdDialogContainer,
104-
overlayRef: OverlayRef): MdDialogRef<T> {
105+
overlayRef: OverlayRef,
106+
config?: MdDialogConfig): MdDialogRef<T> {
105107
// Create a reference to the dialog we're creating in order to give the user a handle
106108
// to modify and close it.
107109
let dialogRef = <MdDialogRef<T>> new MdDialogRef(overlayRef);
@@ -117,7 +119,8 @@ export class MdDialog {
117119
// We create an injector specifically for the component we're instantiating so that it can
118120
// inject the MdDialogRef. This allows a component loaded inside of a dialog to close itself
119121
// and, optionally, to return a value.
120-
let dialogInjector = new DialogInjector(dialogRef, this._injector);
122+
let userInjector = config && config.viewContainerRef && config.viewContainerRef.injector;
123+
let dialogInjector = new DialogInjector(dialogRef, userInjector || this._injector);
121124

122125
let contentPortal = new ComponentPortal(component, null, dialogInjector);
123126

0 commit comments

Comments
 (0)