Skip to content

Commit 0cda47c

Browse files
crisbetotinayuangao
authored andcommitted
fix(overlay): injection errors for scroll strategy providers in lazy-loaded modules (#11213)
Fixes injection errors being thrown by the overlay-based providers that have injection tokens for the default scroll strategy. The error comes from the fact that the scroll strategies were being provided at the root, whereas the `Overlay` provider was provided normally, causing it to be missing when a module is lazy-loaded. Fixes #10820.
1 parent 2815607 commit 0cda47c

File tree

11 files changed

+71
-59
lines changed

11 files changed

+71
-59
lines changed

src/cdk/overlay/overlay-directives.ts

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,13 @@ import {Direction, Directionality} from '@angular/cdk/bidi';
1010
import {coerceBooleanProperty} from '@angular/cdk/coercion';
1111
import {ESCAPE} from '@angular/cdk/keycodes';
1212
import {TemplatePortal} from '@angular/cdk/portal';
13-
import {ScrollDispatcher, ViewportRuler} from '@angular/cdk/scrolling';
1413
import {
1514
Directive,
1615
ElementRef,
1716
EventEmitter,
1817
Inject,
19-
inject,
2018
InjectionToken,
2119
Input,
22-
NgZone,
2320
OnChanges,
2421
OnDestroy,
2522
Optional,
@@ -74,20 +71,12 @@ const defaultPositionList: ConnectedPosition[] = [
7471

7572
/** Injection token that determines the scroll handling while the connected overlay is open. */
7673
export const CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY =
77-
new InjectionToken<() => ScrollStrategy>('cdk-connected-overlay-scroll-strategy', {
78-
providedIn: 'root',
79-
factory: CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY_FACTORY,
80-
});
74+
new InjectionToken<() => ScrollStrategy>('cdk-connected-overlay-scroll-strategy');
8175

82-
/** @docs-private */
83-
export function CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY_FACTORY(): () => ScrollStrategy {
84-
// Store the injected deps here because we can't use the `inject` function outside
85-
// this function's context (including the inner function).
86-
const scrollDispatcher = inject(ScrollDispatcher);
87-
const viewportRuler = inject(ViewportRuler);
88-
const ngZone = inject(NgZone);
89-
return (config?: RepositionScrollStrategyConfig) =>
90-
new RepositionScrollStrategy(scrollDispatcher, viewportRuler, ngZone, config);
76+
/** @docs-private @deprecated @deletion-target 7.0.0 */
77+
export function CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY_FACTORY(overlay: Overlay):
78+
() => ScrollStrategy {
79+
return (config?: RepositionScrollStrategyConfig) => overlay.scrollStrategies.reposition(config);
9180
}
9281

9382
/**
@@ -394,13 +383,13 @@ export class CdkConnectedOverlay implements OnDestroy, OnChanges {
394383
}
395384

396385

397-
/** @docs-private @deprecated @deletion-target 7.0.0 */
386+
/** @docs-private */
398387
export function CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY_PROVIDER_FACTORY(overlay: Overlay):
399388
() => RepositionScrollStrategy {
400389
return () => overlay.scrollStrategies.reposition();
401390
}
402391

403-
/** @docs-private @deprecated @deletion-target 7.0.0 */
392+
/** @docs-private */
404393
export const CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY_PROVIDER = {
405394
provide: CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY,
406395
deps: [Overlay],

src/cdk/overlay/overlay-module.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@ import {OverlayPositionBuilder} from './position/overlay-position-builder';
2525
imports: [BidiModule, PortalModule, ScrollDispatchModule],
2626
exports: [CdkConnectedOverlay, CdkOverlayOrigin, ScrollDispatchModule],
2727
declarations: [CdkConnectedOverlay, CdkOverlayOrigin],
28-
providers: [Overlay],
28+
providers: [
29+
Overlay,
30+
CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY_PROVIDER,
31+
],
2932
})
3033
export class OverlayModule {}
3134

src/lib/autocomplete/autocomplete-module.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ import {CommonModule} from '@angular/common';
1111
import {OverlayModule} from '@angular/cdk/overlay';
1212
import {MatOptionModule, MatCommonModule} from '@angular/material/core';
1313
import {MatAutocomplete} from './autocomplete';
14-
import {MatAutocompleteTrigger} from './autocomplete-trigger';
14+
import {
15+
MatAutocompleteTrigger,
16+
MAT_AUTOCOMPLETE_SCROLL_STRATEGY_FACTORY_PROVIDER,
17+
} from './autocomplete-trigger';
1518
import {MatAutocompleteOrigin} from './autocomplete-origin';
1619

1720
@NgModule({
@@ -24,5 +27,6 @@ import {MatAutocompleteOrigin} from './autocomplete-origin';
2427
MatCommonModule
2528
],
2629
declarations: [MatAutocomplete, MatAutocompleteTrigger, MatAutocompleteOrigin],
30+
providers: [MAT_AUTOCOMPLETE_SCROLL_STRATEGY_FACTORY_PROVIDER],
2731
})
2832
export class MatAutocompleteModule {}

src/lib/autocomplete/autocomplete-trigger.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import {
2626
forwardRef,
2727
Host,
2828
Inject,
29-
inject,
3029
InjectionToken,
3130
Input,
3231
NgZone,
@@ -62,17 +61,20 @@ export const AUTOCOMPLETE_PANEL_HEIGHT = 256;
6261

6362
/** Injection token that determines the scroll handling while the autocomplete panel is open. */
6463
export const MAT_AUTOCOMPLETE_SCROLL_STRATEGY =
65-
new InjectionToken<() => ScrollStrategy>('mat-autocomplete-scroll-strategy', {
66-
providedIn: 'root',
67-
factory: MAT_AUTOCOMPLETE_SCROLL_STRATEGY_FACTORY,
68-
});
64+
new InjectionToken<() => ScrollStrategy>('mat-autocomplete-scroll-strategy');
6965

7066
/** @docs-private */
71-
export function MAT_AUTOCOMPLETE_SCROLL_STRATEGY_FACTORY(): () => ScrollStrategy {
72-
const overlay = inject(Overlay);
67+
export function MAT_AUTOCOMPLETE_SCROLL_STRATEGY_FACTORY(overlay: Overlay): () => ScrollStrategy {
7368
return () => overlay.scrollStrategies.reposition();
7469
}
7570

71+
/** @docs-private */
72+
export const MAT_AUTOCOMPLETE_SCROLL_STRATEGY_FACTORY_PROVIDER = {
73+
provide: MAT_AUTOCOMPLETE_SCROLL_STRATEGY,
74+
deps: [Overlay],
75+
useFactory: MAT_AUTOCOMPLETE_SCROLL_STRATEGY_FACTORY,
76+
};
77+
7678
/**
7779
* Provider that allows the autocomplete to register as a ControlValueAccessor.
7880
* @docs-private

src/lib/datepicker/datepicker-module.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@ import {MatButtonModule} from '@angular/material/button';
1515
import {MatDialogModule} from '@angular/material/dialog';
1616
import {MatCalendar, MatCalendarHeader} from './calendar';
1717
import {MatCalendarBody} from './calendar-body';
18-
import {MatDatepicker, MatDatepickerContent} from './datepicker';
18+
import {
19+
MatDatepicker,
20+
MatDatepickerContent,
21+
MAT_DATEPICKER_SCROLL_STRATEGY_FACTORY_PROVIDER,
22+
} from './datepicker';
1923
import {MatDatepickerInput} from './datepicker-input';
2024
import {MatDatepickerIntl} from './datepicker-intl';
2125
import {MatDatepickerToggle, MatDatepickerToggleIcon} from './datepicker-toggle';
@@ -61,6 +65,7 @@ import {MatYearView} from './year-view';
6165
],
6266
providers: [
6367
MatDatepickerIntl,
68+
MAT_DATEPICKER_SCROLL_STRATEGY_FACTORY_PROVIDER,
6469
],
6570
entryComponents: [
6671
MatDatepickerContent,

src/lib/datepicker/datepicker.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import {
2727
ElementRef,
2828
EventEmitter,
2929
Inject,
30-
inject,
3130
InjectionToken,
3231
Input,
3332
NgZone,
@@ -51,17 +50,20 @@ let datepickerUid = 0;
5150

5251
/** Injection token that determines the scroll handling while the calendar is open. */
5352
export const MAT_DATEPICKER_SCROLL_STRATEGY =
54-
new InjectionToken<() => ScrollStrategy>('mat-datepicker-scroll-strategy', {
55-
providedIn: 'root',
56-
factory: MAT_DATEPICKER_SCROLL_STRATEGY_FACTORY,
57-
});
53+
new InjectionToken<() => ScrollStrategy>('mat-datepicker-scroll-strategy');
5854

5955
/** @docs-private */
60-
export function MAT_DATEPICKER_SCROLL_STRATEGY_FACTORY(): () => ScrollStrategy {
61-
const overlay = inject(Overlay);
56+
export function MAT_DATEPICKER_SCROLL_STRATEGY_FACTORY(overlay: Overlay): () => ScrollStrategy {
6257
return () => overlay.scrollStrategies.reposition();
6358
}
6459

60+
/** @docs-private */
61+
export const MAT_DATEPICKER_SCROLL_STRATEGY_FACTORY_PROVIDER = {
62+
provide: MAT_DATEPICKER_SCROLL_STRATEGY,
63+
deps: [Overlay],
64+
useFactory: MAT_DATEPICKER_SCROLL_STRATEGY_FACTORY,
65+
};
66+
6567
// Boilerplate for applying mixins to MatDatepickerContent.
6668
/** @docs-private */
6769
export class MatDatepickerContentBase {

src/lib/dialog/dialog.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import {ComponentPortal, ComponentType, PortalInjector, TemplatePortal} from '@a
1818
import {Location} from '@angular/common';
1919
import {
2020
Inject,
21-
inject,
2221
Injectable,
2322
InjectionToken,
2423
Injector,
@@ -42,14 +41,10 @@ export const MAT_DIALOG_DEFAULT_OPTIONS =
4241

4342
/** Injection token that determines the scroll handling while the dialog is open. */
4443
export const MAT_DIALOG_SCROLL_STRATEGY =
45-
new InjectionToken<() => ScrollStrategy>('mat-dialog-scroll-strategy', {
46-
providedIn: 'root',
47-
factory: MAT_DIALOG_SCROLL_STRATEGY_FACTORY,
48-
});
44+
new InjectionToken<() => ScrollStrategy>('mat-dialog-scroll-strategy');
4945

5046
/** @docs-private */
51-
export function MAT_DIALOG_SCROLL_STRATEGY_FACTORY(): () => ScrollStrategy {
52-
const overlay = inject(Overlay);
47+
export function MAT_DIALOG_SCROLL_STRATEGY_FACTORY(overlay: Overlay): () => ScrollStrategy {
5348
return () => overlay.scrollStrategies.block();
5449
}
5550

src/lib/menu/menu-module.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ import {MatCommonModule, MatRippleModule} from '@angular/material/core';
1313
import {MatMenuContent} from './menu-content';
1414
import {MatMenu} from './menu-directive';
1515
import {MatMenuItem} from './menu-item';
16-
import {MatMenuTrigger} from './menu-trigger';
16+
import {
17+
MatMenuTrigger,
18+
MAT_MENU_SCROLL_STRATEGY_FACTORY_PROVIDER,
19+
} from './menu-trigger';
1720

1821

1922
@NgModule({
@@ -25,5 +28,6 @@ import {MatMenuTrigger} from './menu-trigger';
2528
],
2629
exports: [MatMenu, MatMenuItem, MatMenuTrigger, MatMenuContent, MatCommonModule],
2730
declarations: [MatMenu, MatMenuItem, MatMenuTrigger, MatMenuContent],
31+
providers: [MAT_MENU_SCROLL_STRATEGY_FACTORY_PROVIDER]
2832
})
2933
export class MatMenuModule {}

src/lib/menu/menu-trigger.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ import {
2525
ElementRef,
2626
EventEmitter,
2727
Inject,
28-
inject,
2928
InjectionToken,
3029
Input,
3130
OnDestroy,
@@ -44,17 +43,20 @@ import {MenuPositionX, MenuPositionY} from './menu-positions';
4443

4544
/** Injection token that determines the scroll handling while the menu is open. */
4645
export const MAT_MENU_SCROLL_STRATEGY =
47-
new InjectionToken<() => ScrollStrategy>('mat-menu-scroll-strategy', {
48-
providedIn: 'root',
49-
factory: MAT_MENU_SCROLL_STRATEGY_FACTORY,
50-
});
46+
new InjectionToken<() => ScrollStrategy>('mat-menu-scroll-strategy');
5147

5248
/** @docs-private */
53-
export function MAT_MENU_SCROLL_STRATEGY_FACTORY(): () => ScrollStrategy {
54-
const overlay = inject(Overlay);
49+
export function MAT_MENU_SCROLL_STRATEGY_FACTORY(overlay: Overlay): () => ScrollStrategy {
5550
return () => overlay.scrollStrategies.reposition();
5651
}
5752

53+
/** @docs-private */
54+
export const MAT_MENU_SCROLL_STRATEGY_FACTORY_PROVIDER = {
55+
provide: MAT_MENU_SCROLL_STRATEGY,
56+
deps: [Overlay],
57+
useFactory: MAT_MENU_SCROLL_STRATEGY_FACTORY,
58+
};
59+
5860
/** Default top padding of the menu panel. */
5961
export const MENU_PANEL_TOP_PADDING = 8;
6062

src/lib/tooltip/tooltip-module.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,11 @@ import {OverlayModule} from '@angular/cdk/overlay';
1010
import {CommonModule} from '@angular/common';
1111
import {NgModule} from '@angular/core';
1212
import {MatCommonModule} from '@angular/material/core';
13-
import {MatTooltip, TooltipComponent} from './tooltip';
14-
13+
import {
14+
MatTooltip,
15+
TooltipComponent,
16+
MAT_TOOLTIP_SCROLL_STRATEGY_FACTORY_PROVIDER,
17+
} from './tooltip';
1518

1619
@NgModule({
1720
imports: [
@@ -22,5 +25,6 @@ import {MatTooltip, TooltipComponent} from './tooltip';
2225
exports: [MatTooltip, TooltipComponent, MatCommonModule],
2326
declarations: [MatTooltip, TooltipComponent],
2427
entryComponents: [TooltipComponent],
28+
providers: [MAT_TOOLTIP_SCROLL_STRATEGY_FACTORY_PROVIDER]
2529
})
2630
export class MatTooltipModule {}

src/lib/tooltip/tooltip.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ import {
3232
Directive,
3333
ElementRef,
3434
Inject,
35-
inject,
3635
InjectionToken,
3736
Input,
3837
NgZone,
@@ -60,17 +59,20 @@ export function getMatTooltipInvalidPositionError(position: string) {
6059

6160
/** Injection token that determines the scroll handling while a tooltip is visible. */
6261
export const MAT_TOOLTIP_SCROLL_STRATEGY =
63-
new InjectionToken<() => ScrollStrategy>('mat-tooltip-scroll-strategy', {
64-
providedIn: 'root',
65-
factory: MAT_TOOLTIP_SCROLL_STRATEGY_FACTORY,
66-
});
62+
new InjectionToken<() => ScrollStrategy>('mat-tooltip-scroll-strategy');
6763

6864
/** @docs-private */
69-
export function MAT_TOOLTIP_SCROLL_STRATEGY_FACTORY(): () => ScrollStrategy {
70-
const overlay = inject(Overlay);
65+
export function MAT_TOOLTIP_SCROLL_STRATEGY_FACTORY(overlay: Overlay): () => ScrollStrategy {
7166
return () => overlay.scrollStrategies.reposition({scrollThrottle: SCROLL_THROTTLE_MS});
7267
}
7368

69+
/** @docs-private */
70+
export const MAT_TOOLTIP_SCROLL_STRATEGY_FACTORY_PROVIDER = {
71+
provide: MAT_TOOLTIP_SCROLL_STRATEGY,
72+
deps: [Overlay],
73+
useFactory: MAT_TOOLTIP_SCROLL_STRATEGY_FACTORY,
74+
};
75+
7476
/** Default `matTooltip` options that can be overridden. */
7577
export interface MatTooltipDefaultOptions {
7678
showDelay: number;

0 commit comments

Comments
 (0)