mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
feat(angular): add custom injector support for modal and popover controllers (#30899)
Issue number: resolves #30638 --------- <!-- Please do not submit updates to dependencies unless it fixes an issue. --> <!-- Please try to limit your pull request to one type (bugfix, feature, etc). Submit multiple pull requests if needed. --> ## What is the current behavior? When using `ModalController.create()` or `PopoverController.create()` in Angular, components rendered inside overlays cannot access non-global services or tokens from the component tree. For example, route-scoped services or Angular's Dir directive for bidirectional text support are not accessible from within a modal, requiring complex workarounds with wrapper components. ## What is the new behavior? `ModalController.create()` and `PopoverController.create()` now accept an optional injector property that allows passing a custom Angular Injector. This enables overlay components to access services and tokens that are not available in the root injector, such as route-scoped services or the Dir directive from Angular CDK. ```typescript const customInjector = Injector.create({ providers: [{ provide: MyService, useValue: myServiceInstance }], parent: this.injector, }); ``` ```typescript const modal = await this.modalController.create({ component: MyModalComponent, injector: customInjector, }); ``` ## Does this introduce a breaking change? - [ ] Yes - [X] No <!-- If this introduces a breaking change: 1. Describe the impact and migration path for existing applications below. 2. Update the BREAKING.md file with the breaking change. 3. Add "BREAKING CHANGE: [...]" to the commit description when merging. See https://github.com/ionic-team/ionic-framework/blob/main/docs/CONTRIBUTING.md#footer for more information. --> ## Other information <!-- Any other information that is important to this PR such as screenshots of how the component looks before and after the change. --> Current dev build: ``` 8.7.17-dev.11769628168.11eca7cd ```
This commit is contained in:
@@ -9,6 +9,7 @@ export { AngularDelegate, bindLifecycleEvents, IonModalToken } from './providers
|
||||
|
||||
export type { IonicWindow } from './types/interfaces';
|
||||
export type { ViewDidEnter, ViewDidLeave, ViewWillEnter, ViewWillLeave } from './types/ionic-lifecycle-hooks';
|
||||
export type { ModalOptions, PopoverOptions } from './types/overlay-options';
|
||||
|
||||
export { NavParams } from './directives/navigation/nav-params';
|
||||
|
||||
|
||||
@@ -36,7 +36,8 @@ export class AngularDelegate {
|
||||
create(
|
||||
environmentInjector: EnvironmentInjector,
|
||||
injector: Injector,
|
||||
elementReferenceKey?: string
|
||||
elementReferenceKey?: string,
|
||||
customInjector?: Injector
|
||||
): AngularFrameworkDelegate {
|
||||
return new AngularFrameworkDelegate(
|
||||
environmentInjector,
|
||||
@@ -44,7 +45,8 @@ export class AngularDelegate {
|
||||
this.applicationRef,
|
||||
this.zone,
|
||||
elementReferenceKey,
|
||||
this.config.useSetInputAPI ?? false
|
||||
this.config.useSetInputAPI ?? false,
|
||||
customInjector
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -59,7 +61,8 @@ export class AngularFrameworkDelegate implements FrameworkDelegate {
|
||||
private applicationRef: ApplicationRef,
|
||||
private zone: NgZone,
|
||||
private elementReferenceKey?: string,
|
||||
private enableSignalsSupport?: boolean
|
||||
private enableSignalsSupport?: boolean,
|
||||
private customInjector?: Injector
|
||||
) {}
|
||||
|
||||
attachViewToDom(container: any, component: any, params?: any, cssClasses?: string[]): Promise<any> {
|
||||
@@ -93,7 +96,8 @@ export class AngularFrameworkDelegate implements FrameworkDelegate {
|
||||
componentProps,
|
||||
cssClasses,
|
||||
this.elementReferenceKey,
|
||||
this.enableSignalsSupport
|
||||
this.enableSignalsSupport,
|
||||
this.customInjector
|
||||
);
|
||||
resolve(el);
|
||||
});
|
||||
@@ -131,7 +135,8 @@ export const attachView = (
|
||||
params: any,
|
||||
cssClasses: string[] | undefined,
|
||||
elementReferenceKey: string | undefined,
|
||||
enableSignalsSupport: boolean | undefined
|
||||
enableSignalsSupport: boolean | undefined,
|
||||
customInjector?: Injector
|
||||
): any => {
|
||||
/**
|
||||
* Wraps the injector with a custom injector that
|
||||
@@ -158,7 +163,7 @@ export const attachView = (
|
||||
|
||||
const childInjector = Injector.create({
|
||||
providers,
|
||||
parent: injector,
|
||||
parent: customInjector ?? injector,
|
||||
});
|
||||
|
||||
const componentRef = createComponent<any>(component, {
|
||||
|
||||
18
packages/angular/common/src/types/overlay-options.ts
Normal file
18
packages/angular/common/src/types/overlay-options.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import type { Injector } from '@angular/core';
|
||||
import type { ModalOptions as CoreModalOptions, PopoverOptions as CorePopoverOptions } from '@ionic/core/components';
|
||||
|
||||
/**
|
||||
* Modal options with Angular-specific injector support.
|
||||
* Extends @ionic/core ModalOptions with an optional injector property.
|
||||
*/
|
||||
export type ModalOptions = CoreModalOptions & {
|
||||
injector?: Injector;
|
||||
};
|
||||
|
||||
/**
|
||||
* Popover options with Angular-specific injector support.
|
||||
* Extends @ionic/core PopoverOptions with an optional injector property.
|
||||
*/
|
||||
export type PopoverOptions = CorePopoverOptions & {
|
||||
injector?: Injector;
|
||||
};
|
||||
Reference in New Issue
Block a user