mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-16 10:01:59 +08:00
feat(angular): support binding routing data to component inputs (#27694)
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`
This commit is contained in:
@ -1,85 +1,7 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { Routes, RouterModule } from '@angular/router';
|
||||
import { InputsComponent } from './inputs/inputs.component';
|
||||
import { ModalComponent } from './modal/modal.component';
|
||||
import { RouterLinkComponent } from './router-link/router-link.component';
|
||||
import { RouterLinkPageComponent } from './router-link-page/router-link-page.component';
|
||||
import { RouterLinkPage2Component } from './router-link-page2/router-link-page2.component';
|
||||
import { RouterLinkPage3Component } from './router-link-page3/router-link-page3.component';
|
||||
import { HomePageComponent } from './home-page/home-page.component';
|
||||
import { NestedOutletComponent } from './nested-outlet/nested-outlet.component';
|
||||
import { NestedOutletPageComponent } from './nested-outlet-page/nested-outlet-page.component';
|
||||
import { NestedOutletPage2Component } from './nested-outlet-page2/nested-outlet-page2.component';
|
||||
import { ViewChildComponent } from './view-child/view-child.component';
|
||||
import { ProvidersComponent } from './providers/providers.component';
|
||||
import { FormComponent } from './form/form.component';
|
||||
import { NavigationPage1Component } from './navigation-page1/navigation-page1.component';
|
||||
import { NavigationPage2Component } from './navigation-page2/navigation-page2.component';
|
||||
import { NavigationPage3Component } from './navigation-page3/navigation-page3.component';
|
||||
import { AlertComponent } from './alert/alert.component';
|
||||
import { AccordionComponent } from './accordion/accordion.component';
|
||||
import { RouterModule } from '@angular/router';
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: '', component: HomePageComponent },
|
||||
{ path: 'version-test', loadChildren: () => import('./version-test').then(m => m.VersionTestModule) },
|
||||
{ path: 'accordions', component: AccordionComponent },
|
||||
{ path: 'alerts', component: AlertComponent },
|
||||
{ path: 'inputs', component: InputsComponent },
|
||||
{ path: 'textarea', loadChildren: () => import('./textarea/textarea.module').then(m => m.TextareaModule) },
|
||||
{ path: 'searchbar', loadChildren: () => import('./searchbar/searchbar.module').then(m => m.SearchbarModule) },
|
||||
{ path: 'form', component: FormComponent },
|
||||
{ path: 'modals', component: ModalComponent },
|
||||
{ path: 'modal-inline', loadChildren: () => import('./modal-inline').then(m => m.ModalInlineModule) },
|
||||
{ path: 'view-child', component: ViewChildComponent },
|
||||
{ path: 'keep-contents-mounted', loadChildren: () => import('./keep-contents-mounted').then(m => m.OverlayAutoMountModule) },
|
||||
{ path: 'overlays-inline', loadChildren: () => import('./overlays-inline').then(m => m.OverlaysInlineModule) },
|
||||
{ path: 'popover-inline', loadChildren: () => import('./popover-inline').then(m => m.PopoverInlineModule) },
|
||||
{ path: 'providers', component: ProvidersComponent },
|
||||
{ path: 'router-link', component: RouterLinkComponent },
|
||||
{ path: 'router-link-page', component: RouterLinkPageComponent },
|
||||
{ path: 'router-link-page2/:id', component: RouterLinkPage2Component },
|
||||
{ path: 'router-link-page3', component: RouterLinkPage3Component },
|
||||
{ path: 'standalone', loadComponent: () => import('./standalone/standalone.component').then(c => c.StandaloneComponent) },
|
||||
{ path: 'tabs', redirectTo: '/tabs/account', pathMatch: 'full' },
|
||||
{
|
||||
path: 'navigation',
|
||||
children: [
|
||||
{ path: 'page1', component: NavigationPage1Component },
|
||||
{ path: 'page2', component: NavigationPage2Component },
|
||||
{ path: 'page3', component: NavigationPage3Component }
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'tabs',
|
||||
loadChildren: () => import('./tabs/tabs.module').then(m => m.TabsPageModule)
|
||||
},
|
||||
{
|
||||
path: 'tabs-global',
|
||||
loadChildren: () => import('./tabs-global/tabs-global.module').then(m => m.TabsGlobalModule)
|
||||
},
|
||||
{
|
||||
path: 'tabs-slots',
|
||||
loadComponent: () => import('./tabs-slots.component').then(c => c.TabsSlotsComponent)
|
||||
},
|
||||
{
|
||||
path: 'nested-outlet',
|
||||
component: NestedOutletComponent,
|
||||
children: [
|
||||
{
|
||||
path: 'page',
|
||||
component: NestedOutletPageComponent
|
||||
},
|
||||
{
|
||||
path: 'page2',
|
||||
component: NestedOutletPage2Component
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'form-controls/range',
|
||||
loadChildren: () => import('./form-controls/range/range.module').then(m => m.RangeModule)
|
||||
}
|
||||
];
|
||||
import { routes } from './app.routes';
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forRoot(routes)],
|
||||
|
82
packages/angular/test/base/src/app/app.routes.ts
Normal file
82
packages/angular/test/base/src/app/app.routes.ts
Normal file
@ -0,0 +1,82 @@
|
||||
import { Routes } from '@angular/router';
|
||||
import { InputsComponent } from './inputs/inputs.component';
|
||||
import { ModalComponent } from './modal/modal.component';
|
||||
import { RouterLinkComponent } from './router-link/router-link.component';
|
||||
import { RouterLinkPageComponent } from './router-link-page/router-link-page.component';
|
||||
import { RouterLinkPage2Component } from './router-link-page2/router-link-page2.component';
|
||||
import { RouterLinkPage3Component } from './router-link-page3/router-link-page3.component';
|
||||
import { HomePageComponent } from './home-page/home-page.component';
|
||||
import { NestedOutletComponent } from './nested-outlet/nested-outlet.component';
|
||||
import { NestedOutletPageComponent } from './nested-outlet-page/nested-outlet-page.component';
|
||||
import { NestedOutletPage2Component } from './nested-outlet-page2/nested-outlet-page2.component';
|
||||
import { ViewChildComponent } from './view-child/view-child.component';
|
||||
import { ProvidersComponent } from './providers/providers.component';
|
||||
import { FormComponent } from './form/form.component';
|
||||
import { NavigationPage1Component } from './navigation-page1/navigation-page1.component';
|
||||
import { NavigationPage2Component } from './navigation-page2/navigation-page2.component';
|
||||
import { NavigationPage3Component } from './navigation-page3/navigation-page3.component';
|
||||
import { AlertComponent } from './alert/alert.component';
|
||||
import { AccordionComponent } from './accordion/accordion.component';
|
||||
|
||||
export const routes: Routes = [
|
||||
{ path: '', component: HomePageComponent },
|
||||
{ path: 'version-test', loadChildren: () => import('./version-test').then(m => m.VersionTestModule) },
|
||||
{ path: 'accordions', component: AccordionComponent },
|
||||
{ path: 'alerts', component: AlertComponent },
|
||||
{ path: 'inputs', component: InputsComponent },
|
||||
{ path: 'textarea', loadChildren: () => import('./textarea/textarea.module').then(m => m.TextareaModule) },
|
||||
{ path: 'searchbar', loadChildren: () => import('./searchbar/searchbar.module').then(m => m.SearchbarModule) },
|
||||
{ path: 'form', component: FormComponent },
|
||||
{ path: 'modals', component: ModalComponent },
|
||||
{ path: 'modal-inline', loadChildren: () => import('./modal-inline').then(m => m.ModalInlineModule) },
|
||||
{ path: 'view-child', component: ViewChildComponent },
|
||||
{ path: 'keep-contents-mounted', loadChildren: () => import('./keep-contents-mounted').then(m => m.OverlayAutoMountModule) },
|
||||
{ path: 'overlays-inline', loadChildren: () => import('./overlays-inline').then(m => m.OverlaysInlineModule) },
|
||||
{ path: 'popover-inline', loadChildren: () => import('./popover-inline').then(m => m.PopoverInlineModule) },
|
||||
{ path: 'providers', component: ProvidersComponent },
|
||||
{ path: 'router-link', component: RouterLinkComponent },
|
||||
{ path: 'router-link-page', component: RouterLinkPageComponent },
|
||||
{ path: 'router-link-page2/:id', component: RouterLinkPage2Component },
|
||||
{ path: 'router-link-page3', component: RouterLinkPage3Component },
|
||||
{ path: 'standalone', loadComponent: () => import('./standalone/standalone.component').then(c => c.StandaloneComponent) },
|
||||
{ path: 'tabs', redirectTo: '/tabs/account', pathMatch: 'full' },
|
||||
{
|
||||
path: 'navigation',
|
||||
children: [
|
||||
{ path: 'page1', component: NavigationPage1Component },
|
||||
{ path: 'page2', component: NavigationPage2Component },
|
||||
{ path: 'page3', component: NavigationPage3Component }
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'tabs',
|
||||
loadChildren: () => import('./tabs/tabs.module').then(m => m.TabsPageModule)
|
||||
},
|
||||
{
|
||||
path: 'tabs-global',
|
||||
loadChildren: () => import('./tabs-global/tabs-global.module').then(m => m.TabsGlobalModule)
|
||||
},
|
||||
{
|
||||
path: 'tabs-slots',
|
||||
loadComponent: () => import('./tabs-slots.component').then(c => c.TabsSlotsComponent)
|
||||
},
|
||||
{
|
||||
path: 'nested-outlet',
|
||||
component: NestedOutletComponent,
|
||||
children: [
|
||||
{
|
||||
path: 'page',
|
||||
component: NestedOutletPageComponent
|
||||
},
|
||||
{
|
||||
path: 'page2',
|
||||
component: NestedOutletPage2Component
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'form-controls/range',
|
||||
loadChildren: () => import('./form-controls/range/range.module').then(m => m.RangeModule)
|
||||
}
|
||||
];
|
||||
|
Reference in New Issue
Block a user