Skip to content

Commit aa19b30

Browse files
crisbetotinayuangao
authored andcommitted
refactor(dialog,bottom-sheet,snack-bar): use injector to pass config to container instance (#11302)
Uses DI to pass in the config object to the various global overlay containers. Compared to the current approach, using the injector has the advantage of allowing the config to be used in the constructor and not having to null-check it everywhere.
1 parent 83b1743 commit aa19b30

File tree

9 files changed

+66
-52
lines changed

9 files changed

+66
-52
lines changed

src/cdk-experimental/dialog/dialog-container.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,9 @@ export class CdkDialogContainer extends BasePortalOutlet {
8080
@HostBinding('attr.aria-label') get _ariaLabel() { return this._config.ariaLabel || null; }
8181

8282
@HostBinding('attr.aria-describedby')
83-
get _ariaDescribedBy() { return this._config ? this._config.ariaDescribedBy : null; }
83+
get _ariaDescribedBy() { return this._config.ariaDescribedBy; }
8484

85-
@HostBinding('attr.role') get _role() { return this._config ? this._config.role : null; }
85+
@HostBinding('attr.role') get _role() { return this._config.role; }
8686

8787
@HostBinding('attr.tabindex') get _tabindex() { return -1; }
8888
// tslint:disable:no-host-decorator-in-concrete
@@ -102,14 +102,13 @@ export class CdkDialogContainer extends BasePortalOutlet {
102102
/** A subject emitting after the dialog exits the view. */
103103
_afterExit: Subject<void> = new Subject();
104104

105-
/** The dialog configuration. */
106-
_config: DialogConfig;
107-
108105
constructor(
109106
private _elementRef: ElementRef,
110107
private _focusTrapFactory: FocusTrapFactory,
111108
private _changeDetectorRef: ChangeDetectorRef,
112-
@Optional() @Inject(DOCUMENT) private _document: any) {
109+
@Optional() @Inject(DOCUMENT) private _document: any,
110+
/** The dialog configuration. */
111+
public _config: DialogConfig) {
113112
super();
114113
}
115114

src/cdk-experimental/dialog/dialog.ts

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,12 @@ export class Dialog {
178178
*/
179179
protected _attachDialogContainer(overlay: OverlayRef, config: DialogConfig): CdkDialogContainer {
180180
const container = config.containerComponent || this.injector.get(DIALOG_CONTAINER);
181-
let containerPortal = new ComponentPortal(container, config.viewContainerRef);
182-
let containerRef: ComponentRef<CdkDialogContainer> = overlay.attach(containerPortal);
181+
const userInjector = config && config.viewContainerRef && config.viewContainerRef.injector;
182+
const injector = new PortalInjector(userInjector || this.injector, new WeakMap([
183+
[DialogConfig, config]
184+
]));
185+
const containerPortal = new ComponentPortal(container, config.viewContainerRef, injector);
186+
const containerRef: ComponentRef<CdkDialogContainer> = overlay.attach(containerPortal);
183187
containerRef.instance._config = config;
184188

185189
return containerRef.instance;
@@ -259,12 +263,11 @@ export class Dialog {
259263
dialogContainer: CdkDialogContainer): PortalInjector {
260264

261265
const userInjector = config && config.viewContainerRef && config.viewContainerRef.injector;
262-
const injectionTokens = new WeakMap();
263-
264-
injectionTokens
265-
.set(this.injector.get(DIALOG_REF), dialogRef)
266-
.set(this.injector.get(DIALOG_CONTAINER), dialogContainer)
267-
.set(DIALOG_DATA, config.data);
266+
const injectionTokens = new WeakMap<any, any>([
267+
[this.injector.get(DIALOG_REF), dialogRef],
268+
[this.injector.get(DIALOG_CONTAINER), dialogContainer],
269+
[DIALOG_DATA, config.data]
270+
]);
268271

269272
if (!userInjector || !userInjector.get(Directionality, null)) {
270273
injectionTokens.set(Directionality, {

src/cdk/overlay/position/flexible-connected-position-strategy.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import {isElementScrolledOutsideView, isElementClippedByScrolling} from './scrol
2222
import {coerceCssPixelValue} from '@angular/cdk/coercion';
2323
import {Platform} from '@angular/cdk/platform';
2424

25-
2625
// TODO: refactor clipping detection into a separate thing (part of scrolling module)
2726
// TODO: attribute selector to specify the transform-origin inside the overlay content
2827
// TODO: flexible position + centering doesn't work on IE11 (works on Edge).

src/lib/bottom-sheet/bottom-sheet-container.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,6 @@ export class MatBottomSheetContainer extends BasePortalOutlet implements OnDestr
7070
/** Emits whenever the state of the animation changes. */
7171
_animationStateChanged = new EventEmitter<AnimationEvent>();
7272

73-
/** The bottom sheet configuration. */
74-
bottomSheetConfig: MatBottomSheetConfig;
75-
7673
/** The class that traps and manages focus within the bottom sheet. */
7774
private _focusTrap: FocusTrap;
7875

@@ -90,7 +87,9 @@ export class MatBottomSheetContainer extends BasePortalOutlet implements OnDestr
9087
private _changeDetectorRef: ChangeDetectorRef,
9188
private _focusTrapFactory: FocusTrapFactory,
9289
breakpointObserver: BreakpointObserver,
93-
@Optional() @Inject(DOCUMENT) document: any) {
90+
@Optional() @Inject(DOCUMENT) document: any,
91+
/** The bottom sheet configuration. */
92+
public bottomSheetConfig: MatBottomSheetConfig) {
9493
super();
9594

9695
this._document = document;

src/lib/bottom-sheet/bottom-sheet.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,15 @@ export class MatBottomSheet {
103103
*/
104104
private _attachContainer(overlayRef: OverlayRef,
105105
config: MatBottomSheetConfig): MatBottomSheetContainer {
106-
const containerPortal = new ComponentPortal(MatBottomSheetContainer, config.viewContainerRef);
106+
107+
const userInjector = config && config.viewContainerRef && config.viewContainerRef.injector;
108+
const injector = new PortalInjector(userInjector || this._injector, new WeakMap([
109+
[MatBottomSheetConfig, config]
110+
]));
111+
112+
const containerPortal =
113+
new ComponentPortal(MatBottomSheetContainer, config.viewContainerRef, injector);
107114
const containerRef: ComponentRef<MatBottomSheetContainer> = overlayRef.attach(containerPortal);
108-
containerRef.instance.bottomSheetConfig = config;
109115
return containerRef.instance;
110116
}
111117

@@ -141,10 +147,10 @@ export class MatBottomSheet {
141147
bottomSheetRef: MatBottomSheetRef<T>): PortalInjector {
142148

143149
const userInjector = config && config.viewContainerRef && config.viewContainerRef.injector;
144-
const injectionTokens = new WeakMap();
145-
146-
injectionTokens.set(MatBottomSheetRef, bottomSheetRef);
147-
injectionTokens.set(MAT_BOTTOM_SHEET_DATA, config.data);
150+
const injectionTokens = new WeakMap<any, any>([
151+
[MatBottomSheetRef, bottomSheetRef],
152+
[MAT_BOTTOM_SHEET_DATA, config.data]
153+
]);
148154

149155
if (!userInjector || !userInjector.get(Directionality, null)) {
150156
injectionTokens.set(Directionality, {

src/lib/dialog/dialog-container.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,10 @@ export function throwMatDialogContentAlreadyAttachedError() {
6060
'class': 'mat-dialog-container',
6161
'tabindex': '-1',
6262
'[attr.id]': '_id',
63-
'[attr.role]': '_config?.role',
64-
'[attr.aria-labelledby]': '_config?.ariaLabel ? null : _ariaLabelledBy',
65-
'[attr.aria-label]': '_config?.ariaLabel',
66-
'[attr.aria-describedby]': '_config?.ariaDescribedBy || null',
63+
'[attr.role]': '_config.role',
64+
'[attr.aria-labelledby]': '_config.ariaLabel ? null : _ariaLabelledBy',
65+
'[attr.aria-label]': '_config.ariaLabel',
66+
'[attr.aria-describedby]': '_config.ariaDescribedBy || null',
6767
'[@slideDialog]': '_state',
6868
'(@slideDialog.start)': '_onAnimationStart($event)',
6969
'(@slideDialog.done)': '_onAnimationDone($event)',
@@ -79,9 +79,6 @@ export class MatDialogContainer extends BasePortalOutlet {
7979
/** Element that was focused before the dialog was opened. Save this to restore upon close. */
8080
private _elementFocusedBeforeDialogWasOpened: HTMLElement | null = null;
8181

82-
/** The dialog configuration. */
83-
_config: MatDialogConfig;
84-
8582
/** State of the dialog animation. */
8683
_state: 'void' | 'enter' | 'exit' = 'enter';
8784

@@ -98,7 +95,9 @@ export class MatDialogContainer extends BasePortalOutlet {
9895
private _elementRef: ElementRef,
9996
private _focusTrapFactory: FocusTrapFactory,
10097
private _changeDetectorRef: ChangeDetectorRef,
101-
@Optional() @Inject(DOCUMENT) private _document: any) {
98+
@Optional() @Inject(DOCUMENT) private _document: any,
99+
/** The dialog configuration. */
100+
public _config: MatDialogConfig) {
102101

103102
super();
104103
}

src/lib/dialog/dialog.ts

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import {
1717
import {ComponentPortal, ComponentType, PortalInjector, TemplatePortal} from '@angular/cdk/portal';
1818
import {Location} from '@angular/common';
1919
import {
20-
ComponentRef,
2120
Inject,
2221
inject,
2322
Injectable,
@@ -210,9 +209,13 @@ export class MatDialog {
210209
* @returns A promise resolving to a ComponentRef for the attached container.
211210
*/
212211
private _attachDialogContainer(overlay: OverlayRef, config: MatDialogConfig): MatDialogContainer {
213-
let containerPortal = new ComponentPortal(MatDialogContainer, config.viewContainerRef);
214-
let containerRef: ComponentRef<MatDialogContainer> = overlay.attach(containerPortal);
215-
containerRef.instance._config = config;
212+
const userInjector = config && config.viewContainerRef && config.viewContainerRef.injector;
213+
const injector = new PortalInjector(userInjector || this._injector, new WeakMap([
214+
[MatDialogConfig, config]
215+
]));
216+
const containerPortal =
217+
new ComponentPortal(MatDialogContainer, config.viewContainerRef, injector);
218+
const containerRef = overlay.attach<MatDialogContainer>(containerPortal);
216219

217220
return containerRef.instance;
218221
}
@@ -278,16 +281,16 @@ export class MatDialog {
278281
dialogContainer: MatDialogContainer): PortalInjector {
279282

280283
const userInjector = config && config.viewContainerRef && config.viewContainerRef.injector;
281-
const injectionTokens = new WeakMap();
282284

283285
// The MatDialogContainer is injected in the portal as the MatDialogContainer and the dialog's
284286
// content are created out of the same ViewContainerRef and as such, are siblings for injector
285287
// purposes. To allow the hierarchy that is expected, the MatDialogContainer is explicitly
286288
// added to the injection tokens.
287-
injectionTokens
288-
.set(MatDialogContainer, dialogContainer)
289-
.set(MAT_DIALOG_DATA, config.data)
290-
.set(MatDialogRef, dialogRef);
289+
const injectionTokens = new WeakMap<any, any>([
290+
[MatDialogContainer, dialogContainer],
291+
[MAT_DIALOG_DATA, config.data],
292+
[MatDialogRef, dialogRef]
293+
]);
291294

292295
if (!userInjector || !userInjector.get(Directionality, null)) {
293296
injectionTokens.set(Directionality, {

src/lib/snack-bar/snack-bar-container.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,13 @@ export class MatSnackBarContainer extends BasePortalOutlet implements OnDestroy
6666
/** The state of the snack bar animations. */
6767
_animationState = 'void';
6868

69-
/** The snack bar configuration. */
70-
snackBarConfig: MatSnackBarConfig;
71-
7269
constructor(
7370
private _ngZone: NgZone,
7471
private _elementRef: ElementRef,
75-
private _changeDetectorRef: ChangeDetectorRef) {
72+
private _changeDetectorRef: ChangeDetectorRef,
73+
/** The snack bar configuration. */
74+
public snackBarConfig: MatSnackBarConfig) {
75+
7676
super();
7777
}
7878

src/lib/snack-bar/snack-bar.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,14 @@ export class MatSnackBar {
130130
*/
131131
private _attachSnackBarContainer(overlayRef: OverlayRef,
132132
config: MatSnackBarConfig): MatSnackBarContainer {
133-
const containerPortal = new ComponentPortal(MatSnackBarContainer, config.viewContainerRef);
133+
134+
const userInjector = config && config.viewContainerRef && config.viewContainerRef.injector;
135+
const injector = new PortalInjector(userInjector || this._injector, new WeakMap([
136+
[MatSnackBarConfig, config]
137+
]));
138+
139+
const containerPortal =
140+
new ComponentPortal(MatSnackBarContainer, config.viewContainerRef, injector);
134141
const containerRef: ComponentRef<MatSnackBarContainer> = overlayRef.attach(containerPortal);
135142
containerRef.instance.snackBarConfig = config;
136143
return containerRef.instance;
@@ -257,11 +264,10 @@ export class MatSnackBar {
257264
snackBarRef: MatSnackBarRef<T>): PortalInjector {
258265

259266
const userInjector = config && config.viewContainerRef && config.viewContainerRef.injector;
260-
const injectionTokens = new WeakMap();
261-
262-
injectionTokens.set(MatSnackBarRef, snackBarRef);
263-
injectionTokens.set(MAT_SNACK_BAR_DATA, config.data);
264267

265-
return new PortalInjector(userInjector || this._injector, injectionTokens);
268+
return new PortalInjector(userInjector || this._injector, new WeakMap<any, any>([
269+
[MatSnackBarRef, snackBarRef],
270+
[MAT_SNACK_BAR_DATA, config.data]
271+
]));
266272
}
267273
}

0 commit comments

Comments
 (0)