mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-20 20:33:32 +08:00

Issue number: Resolves #27476 --------- <!-- 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? <!-- Please describe the current behavior that you are modifying. --> Ionic Angular application on Angular v16 cannot use the [`bindToComponentInputs`](https://angular.io/api/router/ExtraOptions#bindToComponentInputs) feature to assign route parameters, query parameters, route data and route resolve data to component inputs. ## What is the new behavior? <!-- Please describe the behavior or changes that are being added by this PR. --> - Ionic Angular developers can use the option on `RouterModule.forRoot` to enable the Angular feature for binding the route snapshot data to the component inputs. **Modules** ```ts @NgModule({ imports: [ RouterModule.forRoot([/* your routes */], { bindToComponentInputs: true // <-- enable this feature }) ] }) export class AppModule { } ``` **Standalone** ```ts import { withComponentInputBinding } from '@angular/router'; bootstrapApplication(App, { providers: [ provideRouter(routes, //... other features withComponentInputBinding() // <-- enable this feature ) ], }); ``` With this feature enabled, developers can bind route parameters, query parameters, route data and the returned value from a resolver to input bindings on their component. For example, with a route configuration of: ```ts RouterModule.forChild([ { path: ':id', data: { title: 'Hello world' }, resolve: { name: () => 'Resolved name' }, loadComponent: () => import('./example-component/example.component').then(c => c.ExampleComponent) } ]) ``` and a component configuration of: ```ts @Component({ }) export class ExampleComponent { @Input() id?: string; @Input() title?: string; @Input() name?: string; @Input() query?: string; } ``` Navigating to the component with a url of: `/2?query=searchphrase` The following would occur: - `id` would return `2` - `title` would return `Hello world` - `name` would return `Resolved name` - `query` would return `searchphrase` ## Does this introduce a breaking change? - [ ] Yes - [x] No <!-- If this introduces a breaking change, please describe the impact and migration path for existing applications below. --> ## Other information <!-- Any other information that is important to this PR such as screenshots of how the component looks before and after the change. --> This PR will need to be targeted to a minor release once a design doc is approved by the team. Dev-build: `7.1.3-dev.11689276547.129acb40`
95 lines
2.8 KiB
TypeScript
95 lines
2.8 KiB
TypeScript
import { CommonModule, DOCUMENT } from '@angular/common';
|
|
import { ModuleWithProviders, APP_INITIALIZER, NgModule, NgZone } from '@angular/core';
|
|
import { Router } from '@angular/router';
|
|
import { IonicConfig } from '@ionic/core';
|
|
|
|
import { appInitialize } from './app-initialize';
|
|
import {
|
|
BooleanValueAccessorDirective,
|
|
NumericValueAccessorDirective,
|
|
RadioValueAccessorDirective,
|
|
SelectValueAccessorDirective,
|
|
TextValueAccessorDirective,
|
|
} from './directives/control-value-accessors';
|
|
import { IonBackButtonDelegateDirective } from './directives/navigation/ion-back-button';
|
|
import { INPUT_BINDER, IonRouterOutlet, RoutedComponentInputBinder } from './directives/navigation/ion-router-outlet';
|
|
import { IonTabs } from './directives/navigation/ion-tabs';
|
|
import { NavDelegate } from './directives/navigation/nav-delegate';
|
|
import {
|
|
RouterLinkDelegateDirective,
|
|
RouterLinkWithHrefDelegateDirective,
|
|
} from './directives/navigation/router-link-delegate';
|
|
import { IonModal } from './directives/overlays/modal';
|
|
import { IonPopover } from './directives/overlays/popover';
|
|
import { DIRECTIVES } from './directives/proxies-list';
|
|
import { AngularDelegate } from './providers/angular-delegate';
|
|
import { ConfigToken } from './providers/config';
|
|
import { ModalController } from './providers/modal-controller';
|
|
import { PopoverController } from './providers/popover-controller';
|
|
|
|
const DECLARATIONS = [
|
|
// generated proxies
|
|
...DIRECTIVES,
|
|
|
|
// manual proxies
|
|
IonModal,
|
|
IonPopover,
|
|
|
|
// ngModel accessors
|
|
BooleanValueAccessorDirective,
|
|
NumericValueAccessorDirective,
|
|
RadioValueAccessorDirective,
|
|
SelectValueAccessorDirective,
|
|
TextValueAccessorDirective,
|
|
|
|
// navigation
|
|
IonTabs,
|
|
IonRouterOutlet,
|
|
IonBackButtonDelegateDirective,
|
|
NavDelegate,
|
|
RouterLinkDelegateDirective,
|
|
RouterLinkWithHrefDelegateDirective,
|
|
];
|
|
|
|
@NgModule({
|
|
declarations: DECLARATIONS,
|
|
exports: DECLARATIONS,
|
|
providers: [AngularDelegate, ModalController, PopoverController],
|
|
imports: [CommonModule],
|
|
})
|
|
export class IonicModule {
|
|
static forRoot(config?: IonicConfig): ModuleWithProviders<IonicModule> {
|
|
return {
|
|
ngModule: IonicModule,
|
|
providers: [
|
|
{
|
|
provide: ConfigToken,
|
|
useValue: config,
|
|
},
|
|
{
|
|
provide: APP_INITIALIZER,
|
|
useFactory: appInitialize,
|
|
multi: true,
|
|
deps: [ConfigToken, DOCUMENT, NgZone],
|
|
},
|
|
{
|
|
provide: INPUT_BINDER,
|
|
useFactory: componentInputBindingFactory,
|
|
deps: [Router],
|
|
},
|
|
],
|
|
};
|
|
}
|
|
}
|
|
|
|
function componentInputBindingFactory(router?: Router) {
|
|
/**
|
|
* We cast the router to any here, since the componentInputBindingEnabled
|
|
* property is not available until Angular v16.
|
|
*/
|
|
if ((router as any)?.componentInputBindingEnabled) {
|
|
return new RoutedComponentInputBinder();
|
|
}
|
|
return null;
|
|
}
|