mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
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`.
This commit is contained in:
committed by
mmalerba
parent
c7d1c17768
commit
be0da096ea
@@ -8,7 +8,7 @@ import {
|
||||
tick,
|
||||
} from '@angular/core/testing';
|
||||
import {By} from '@angular/platform-browser';
|
||||
import {NgModule, Component, Directive, ViewChild, ViewContainerRef} from '@angular/core';
|
||||
import {NgModule, Component, Directive, ViewChild, ViewContainerRef, Injector} from '@angular/core';
|
||||
import {MdDialogModule} from './index';
|
||||
import {MdDialog} from './dialog';
|
||||
import {OverlayContainer} from '../core';
|
||||
@@ -64,6 +64,21 @@ describe('MdDialog', () => {
|
||||
expect(dialogContainerElement.getAttribute('role')).toBe('dialog');
|
||||
});
|
||||
|
||||
it('should use injector from viewContainerRef for DialogInjector', () => {
|
||||
let dialogRef = dialog.open(PizzaMsg, {
|
||||
viewContainerRef: testViewContainerRef
|
||||
});
|
||||
|
||||
viewContainerFixture.detectChanges();
|
||||
|
||||
let dialogInjector = dialogRef.componentInstance.dialogInjector;
|
||||
|
||||
expect(dialogRef.componentInstance.dialogRef).toBe(dialogRef);
|
||||
expect(dialogInjector.get(DirectiveWithViewContainer)).toBeTruthy(
|
||||
'Expected the dialog component to be created with the injector from the viewContainerRef.'
|
||||
);
|
||||
});
|
||||
|
||||
it('should open a dialog with a component and no ViewContainerRef', () => {
|
||||
let dialogRef = dialog.open(PizzaMsg);
|
||||
|
||||
@@ -435,7 +450,8 @@ class ComponentWithChildViewContainer {
|
||||
/** Simple component for testing ComponentPortal. */
|
||||
@Component({template: '<p>Pizza</p> <input> <button>Close</button>'})
|
||||
class PizzaMsg {
|
||||
constructor(public dialogRef: MdDialogRef<PizzaMsg>) { }
|
||||
constructor(public dialogRef: MdDialogRef<PizzaMsg>,
|
||||
public dialogInjector: Injector) {}
|
||||
}
|
||||
|
||||
@Component({
|
||||
|
||||
@@ -42,7 +42,7 @@ export class MdDialog {
|
||||
|
||||
let overlayRef = this._createOverlay(config);
|
||||
let dialogContainer = this._attachDialogContainer(overlayRef, config);
|
||||
let dialogRef = this._attachDialogContent(component, dialogContainer, overlayRef);
|
||||
let dialogRef = this._attachDialogContent(component, dialogContainer, overlayRef, config);
|
||||
|
||||
this._openDialogs.push(dialogRef);
|
||||
dialogRef.afterClosed().subscribe(() => this._removeOpenDialog(dialogRef));
|
||||
@@ -96,12 +96,14 @@ export class MdDialog {
|
||||
* @param component The type of component being loaded into the dialog.
|
||||
* @param dialogContainer Reference to the wrapping MdDialogContainer.
|
||||
* @param overlayRef Reference to the overlay in which the dialog resides.
|
||||
* @param config The dialog configuration.
|
||||
* @returns A promise resolving to the MdDialogRef that should be returned to the user.
|
||||
*/
|
||||
private _attachDialogContent<T>(
|
||||
component: ComponentType<T>,
|
||||
dialogContainer: MdDialogContainer,
|
||||
overlayRef: OverlayRef): MdDialogRef<T> {
|
||||
overlayRef: OverlayRef,
|
||||
config?: MdDialogConfig): MdDialogRef<T> {
|
||||
// Create a reference to the dialog we're creating in order to give the user a handle
|
||||
// to modify and close it.
|
||||
let dialogRef = <MdDialogRef<T>> new MdDialogRef(overlayRef);
|
||||
@@ -117,7 +119,8 @@ export class MdDialog {
|
||||
// We create an injector specifically for the component we're instantiating so that it can
|
||||
// inject the MdDialogRef. This allows a component loaded inside of a dialog to close itself
|
||||
// and, optionally, to return a value.
|
||||
let dialogInjector = new DialogInjector(dialogRef, this._injector);
|
||||
let userInjector = config && config.viewContainerRef && config.viewContainerRef.injector;
|
||||
let dialogInjector = new DialogInjector(dialogRef, userInjector || this._injector);
|
||||
|
||||
let contentPortal = new ComponentPortal(component, null, dialogInjector);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user