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.
This commit is contained in:
Kristiyan Kostadinov
2018-05-16 19:55:03 +02:00
committed by tinayuangao
parent 28156078f5
commit 0cda47c490
11 changed files with 71 additions and 59 deletions
+7 -18
View File
@@ -10,16 +10,13 @@ import {Direction, Directionality} from '@angular/cdk/bidi';
import {coerceBooleanProperty} from '@angular/cdk/coercion';
import {ESCAPE} from '@angular/cdk/keycodes';
import {TemplatePortal} from '@angular/cdk/portal';
import {ScrollDispatcher, ViewportRuler} from '@angular/cdk/scrolling';
import {
Directive,
ElementRef,
EventEmitter,
Inject,
inject,
InjectionToken,
Input,
NgZone,
OnChanges,
OnDestroy,
Optional,
@@ -74,20 +71,12 @@ const defaultPositionList: ConnectedPosition[] = [
/** Injection token that determines the scroll handling while the connected overlay is open. */
export const CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY =
new InjectionToken<() => ScrollStrategy>('cdk-connected-overlay-scroll-strategy', {
providedIn: 'root',
factory: CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY_FACTORY,
});
new InjectionToken<() => ScrollStrategy>('cdk-connected-overlay-scroll-strategy');
/** @docs-private */
export function CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY_FACTORY(): () => ScrollStrategy {
// Store the injected deps here because we can't use the `inject` function outside
// this function's context (including the inner function).
const scrollDispatcher = inject(ScrollDispatcher);
const viewportRuler = inject(ViewportRuler);
const ngZone = inject(NgZone);
return (config?: RepositionScrollStrategyConfig) =>
new RepositionScrollStrategy(scrollDispatcher, viewportRuler, ngZone, config);
/** @docs-private @deprecated @deletion-target 7.0.0 */
export function CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY_FACTORY(overlay: Overlay):
() => ScrollStrategy {
return (config?: RepositionScrollStrategyConfig) => overlay.scrollStrategies.reposition(config);
}
/**
@@ -394,13 +383,13 @@ export class CdkConnectedOverlay implements OnDestroy, OnChanges {
}
/** @docs-private @deprecated @deletion-target 7.0.0 */
/** @docs-private */
export function CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY_PROVIDER_FACTORY(overlay: Overlay):
() => RepositionScrollStrategy {
return () => overlay.scrollStrategies.reposition();
}
/** @docs-private @deprecated @deletion-target 7.0.0 */
/** @docs-private */
export const CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY_PROVIDER = {
provide: CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY,
deps: [Overlay],
+4 -1
View File
@@ -25,7 +25,10 @@ import {OverlayPositionBuilder} from './position/overlay-position-builder';
imports: [BidiModule, PortalModule, ScrollDispatchModule],
exports: [CdkConnectedOverlay, CdkOverlayOrigin, ScrollDispatchModule],
declarations: [CdkConnectedOverlay, CdkOverlayOrigin],
providers: [Overlay],
providers: [
Overlay,
CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY_PROVIDER,
],
})
export class OverlayModule {}
+5 -1
View File
@@ -11,7 +11,10 @@ import {CommonModule} from '@angular/common';
import {OverlayModule} from '@angular/cdk/overlay';
import {MatOptionModule, MatCommonModule} from '@angular/material/core';
import {MatAutocomplete} from './autocomplete';
import {MatAutocompleteTrigger} from './autocomplete-trigger';
import {
MatAutocompleteTrigger,
MAT_AUTOCOMPLETE_SCROLL_STRATEGY_FACTORY_PROVIDER,
} from './autocomplete-trigger';
import {MatAutocompleteOrigin} from './autocomplete-origin';
@NgModule({
@@ -24,5 +27,6 @@ import {MatAutocompleteOrigin} from './autocomplete-origin';
MatCommonModule
],
declarations: [MatAutocomplete, MatAutocompleteTrigger, MatAutocompleteOrigin],
providers: [MAT_AUTOCOMPLETE_SCROLL_STRATEGY_FACTORY_PROVIDER],
})
export class MatAutocompleteModule {}
+9 -7
View File
@@ -26,7 +26,6 @@ import {
forwardRef,
Host,
Inject,
inject,
InjectionToken,
Input,
NgZone,
@@ -62,17 +61,20 @@ export const AUTOCOMPLETE_PANEL_HEIGHT = 256;
/** Injection token that determines the scroll handling while the autocomplete panel is open. */
export const MAT_AUTOCOMPLETE_SCROLL_STRATEGY =
new InjectionToken<() => ScrollStrategy>('mat-autocomplete-scroll-strategy', {
providedIn: 'root',
factory: MAT_AUTOCOMPLETE_SCROLL_STRATEGY_FACTORY,
});
new InjectionToken<() => ScrollStrategy>('mat-autocomplete-scroll-strategy');
/** @docs-private */
export function MAT_AUTOCOMPLETE_SCROLL_STRATEGY_FACTORY(): () => ScrollStrategy {
const overlay = inject(Overlay);
export function MAT_AUTOCOMPLETE_SCROLL_STRATEGY_FACTORY(overlay: Overlay): () => ScrollStrategy {
return () => overlay.scrollStrategies.reposition();
}
/** @docs-private */
export const MAT_AUTOCOMPLETE_SCROLL_STRATEGY_FACTORY_PROVIDER = {
provide: MAT_AUTOCOMPLETE_SCROLL_STRATEGY,
deps: [Overlay],
useFactory: MAT_AUTOCOMPLETE_SCROLL_STRATEGY_FACTORY,
};
/**
* Provider that allows the autocomplete to register as a ControlValueAccessor.
* @docs-private
+6 -1
View File
@@ -15,7 +15,11 @@ import {MatButtonModule} from '@angular/material/button';
import {MatDialogModule} from '@angular/material/dialog';
import {MatCalendar, MatCalendarHeader} from './calendar';
import {MatCalendarBody} from './calendar-body';
import {MatDatepicker, MatDatepickerContent} from './datepicker';
import {
MatDatepicker,
MatDatepickerContent,
MAT_DATEPICKER_SCROLL_STRATEGY_FACTORY_PROVIDER,
} from './datepicker';
import {MatDatepickerInput} from './datepicker-input';
import {MatDatepickerIntl} from './datepicker-intl';
import {MatDatepickerToggle, MatDatepickerToggleIcon} from './datepicker-toggle';
@@ -61,6 +65,7 @@ import {MatYearView} from './year-view';
],
providers: [
MatDatepickerIntl,
MAT_DATEPICKER_SCROLL_STRATEGY_FACTORY_PROVIDER,
],
entryComponents: [
MatDatepickerContent,
+9 -7
View File
@@ -27,7 +27,6 @@ import {
ElementRef,
EventEmitter,
Inject,
inject,
InjectionToken,
Input,
NgZone,
@@ -51,17 +50,20 @@ let datepickerUid = 0;
/** Injection token that determines the scroll handling while the calendar is open. */
export const MAT_DATEPICKER_SCROLL_STRATEGY =
new InjectionToken<() => ScrollStrategy>('mat-datepicker-scroll-strategy', {
providedIn: 'root',
factory: MAT_DATEPICKER_SCROLL_STRATEGY_FACTORY,
});
new InjectionToken<() => ScrollStrategy>('mat-datepicker-scroll-strategy');
/** @docs-private */
export function MAT_DATEPICKER_SCROLL_STRATEGY_FACTORY(): () => ScrollStrategy {
const overlay = inject(Overlay);
export function MAT_DATEPICKER_SCROLL_STRATEGY_FACTORY(overlay: Overlay): () => ScrollStrategy {
return () => overlay.scrollStrategies.reposition();
}
/** @docs-private */
export const MAT_DATEPICKER_SCROLL_STRATEGY_FACTORY_PROVIDER = {
provide: MAT_DATEPICKER_SCROLL_STRATEGY,
deps: [Overlay],
useFactory: MAT_DATEPICKER_SCROLL_STRATEGY_FACTORY,
};
// Boilerplate for applying mixins to MatDatepickerContent.
/** @docs-private */
export class MatDatepickerContentBase {
+2 -7
View File
@@ -18,7 +18,6 @@ import {ComponentPortal, ComponentType, PortalInjector, TemplatePortal} from '@a
import {Location} from '@angular/common';
import {
Inject,
inject,
Injectable,
InjectionToken,
Injector,
@@ -42,14 +41,10 @@ export const MAT_DIALOG_DEFAULT_OPTIONS =
/** Injection token that determines the scroll handling while the dialog is open. */
export const MAT_DIALOG_SCROLL_STRATEGY =
new InjectionToken<() => ScrollStrategy>('mat-dialog-scroll-strategy', {
providedIn: 'root',
factory: MAT_DIALOG_SCROLL_STRATEGY_FACTORY,
});
new InjectionToken<() => ScrollStrategy>('mat-dialog-scroll-strategy');
/** @docs-private */
export function MAT_DIALOG_SCROLL_STRATEGY_FACTORY(): () => ScrollStrategy {
const overlay = inject(Overlay);
export function MAT_DIALOG_SCROLL_STRATEGY_FACTORY(overlay: Overlay): () => ScrollStrategy {
return () => overlay.scrollStrategies.block();
}
+5 -1
View File
@@ -13,7 +13,10 @@ import {MatCommonModule, MatRippleModule} from '@angular/material/core';
import {MatMenuContent} from './menu-content';
import {MatMenu} from './menu-directive';
import {MatMenuItem} from './menu-item';
import {MatMenuTrigger} from './menu-trigger';
import {
MatMenuTrigger,
MAT_MENU_SCROLL_STRATEGY_FACTORY_PROVIDER,
} from './menu-trigger';
@NgModule({
@@ -25,5 +28,6 @@ import {MatMenuTrigger} from './menu-trigger';
],
exports: [MatMenu, MatMenuItem, MatMenuTrigger, MatMenuContent, MatCommonModule],
declarations: [MatMenu, MatMenuItem, MatMenuTrigger, MatMenuContent],
providers: [MAT_MENU_SCROLL_STRATEGY_FACTORY_PROVIDER]
})
export class MatMenuModule {}
+9 -7
View File
@@ -25,7 +25,6 @@ import {
ElementRef,
EventEmitter,
Inject,
inject,
InjectionToken,
Input,
OnDestroy,
@@ -44,17 +43,20 @@ import {MenuPositionX, MenuPositionY} from './menu-positions';
/** Injection token that determines the scroll handling while the menu is open. */
export const MAT_MENU_SCROLL_STRATEGY =
new InjectionToken<() => ScrollStrategy>('mat-menu-scroll-strategy', {
providedIn: 'root',
factory: MAT_MENU_SCROLL_STRATEGY_FACTORY,
});
new InjectionToken<() => ScrollStrategy>('mat-menu-scroll-strategy');
/** @docs-private */
export function MAT_MENU_SCROLL_STRATEGY_FACTORY(): () => ScrollStrategy {
const overlay = inject(Overlay);
export function MAT_MENU_SCROLL_STRATEGY_FACTORY(overlay: Overlay): () => ScrollStrategy {
return () => overlay.scrollStrategies.reposition();
}
/** @docs-private */
export const MAT_MENU_SCROLL_STRATEGY_FACTORY_PROVIDER = {
provide: MAT_MENU_SCROLL_STRATEGY,
deps: [Overlay],
useFactory: MAT_MENU_SCROLL_STRATEGY_FACTORY,
};
/** Default top padding of the menu panel. */
export const MENU_PANEL_TOP_PADDING = 8;
+6 -2
View File
@@ -10,8 +10,11 @@ import {OverlayModule} from '@angular/cdk/overlay';
import {CommonModule} from '@angular/common';
import {NgModule} from '@angular/core';
import {MatCommonModule} from '@angular/material/core';
import {MatTooltip, TooltipComponent} from './tooltip';
import {
MatTooltip,
TooltipComponent,
MAT_TOOLTIP_SCROLL_STRATEGY_FACTORY_PROVIDER,
} from './tooltip';
@NgModule({
imports: [
@@ -22,5 +25,6 @@ import {MatTooltip, TooltipComponent} from './tooltip';
exports: [MatTooltip, TooltipComponent, MatCommonModule],
declarations: [MatTooltip, TooltipComponent],
entryComponents: [TooltipComponent],
providers: [MAT_TOOLTIP_SCROLL_STRATEGY_FACTORY_PROVIDER]
})
export class MatTooltipModule {}
+9 -7
View File
@@ -32,7 +32,6 @@ import {
Directive,
ElementRef,
Inject,
inject,
InjectionToken,
Input,
NgZone,
@@ -60,17 +59,20 @@ export function getMatTooltipInvalidPositionError(position: string) {
/** Injection token that determines the scroll handling while a tooltip is visible. */
export const MAT_TOOLTIP_SCROLL_STRATEGY =
new InjectionToken<() => ScrollStrategy>('mat-tooltip-scroll-strategy', {
providedIn: 'root',
factory: MAT_TOOLTIP_SCROLL_STRATEGY_FACTORY,
});
new InjectionToken<() => ScrollStrategy>('mat-tooltip-scroll-strategy');
/** @docs-private */
export function MAT_TOOLTIP_SCROLL_STRATEGY_FACTORY(): () => ScrollStrategy {
const overlay = inject(Overlay);
export function MAT_TOOLTIP_SCROLL_STRATEGY_FACTORY(overlay: Overlay): () => ScrollStrategy {
return () => overlay.scrollStrategies.reposition({scrollThrottle: SCROLL_THROTTLE_MS});
}
/** @docs-private */
export const MAT_TOOLTIP_SCROLL_STRATEGY_FACTORY_PROVIDER = {
provide: MAT_TOOLTIP_SCROLL_STRATEGY,
deps: [Overlay],
useFactory: MAT_TOOLTIP_SCROLL_STRATEGY_FACTORY,
};
/** Default `matTooltip` options that can be overridden. */
export interface MatTooltipDefaultOptions {
showDelay: number;