问题
In my routing module I am passing data in this fashion.
const routes: Routes = [
{ path: '', redirectTo: 'login', pathMatch: 'full' },
{ path: 'login', component: LoginComponent, data: { ShowTopBar: true, showSideBar: false} },
{ path: 'error', component: ErrorComponent, data: { ShowTopBar: true, showSideBar: false}}
];
export const AppRoutingModule: ModuleWithProviders = RouterModule.forRoot(routes);
In order to make the data type safe I have created a RouteData
class which would hold the ShowTopBar
and ShowSideBar
values and initialize them through a constructor.
export class RouteData {
constructor(showTopbar: boolean, showSideBar: boolean) {
this.ShowSideBar = showSideBar;
this.ShowTopBar = showTopbar;
}
public ShowTopBar: boolean;
public ShowSideBar: boolean;
}
Now, I have changed the declarations for Routes in the following manner:
const routes: Routes = [
{ path: '', redirectTo: 'login', pathMatch: 'full' },
{ path: 'login', component: LoginComponent, data: new RouteData(false, false) },
{ path: 'error', component: ErrorComponent, data: new RouteData(true, false)}
];
which is giving the following error on compiling:
Error encountered resolving symbol values statically. Calling function 'RouteData', function calls are not supported. Consider replacing the function or la mbda with a reference to an exported function, resolving symbol AppRoutingModule
My Question is how can we pass RouteData
in a type-safe way to Routes so that I can take advantage of type-safety.
回答1:
you can do below,
extend Route from @angular/router
and update Type of data like below,
export interface RouteData {
ShowTopBar: boolean;
ShowSideBar: boolean;
}
interface CustomRoute extends Route {
data?: RouteData;
}
update type of routes to CustomRoute[]
from Routes
const routes: CustomRoute[] = [
{ path: '', redirectTo: '/home', pathMatch: 'full' },
{ path: 'home', component: HomeComponent, data: { ShowSideBar: true, ShowTopBar: true } }
];
now you can pass Type safe data, see below,
Hope this helps!!
回答2:
I wrote a small library that covers all typings for the standard router.
ngx-typed-router
It allows you to have types for everything starting from router configuration, components, resolvers and ending with tests.
E.g.
export const ExampleRoutes: Routes = [
{
path: 'test/:id',
component: ExampleComponent,
resolve: {
exampleResponse: ExampleResolveService,
} as ResolveConfig<ExampleTestRouteData>,
},
];
export interface ExampleTestRouteQuery {
param1: string;
}
export interface ExampleTestRoutePath {
id: string;
}
export interface ExampleTestRouteData {
exampleResponse: ExampleResponse;
}
Component:
@Component({
selector: 'app-example',
templateUrl: './example.component.html',
styleUrls: ['./example.component.scss']
})
export class ExampleComponent {
constructor(
@Inject(ActivatedRoute) public route: TypedRoute<ExampleTestRouteData, ExampleTestRoutePath, ExampleTestRouteQuery>,
// or
// @Inject(ActivatedRoute) public route: TypedRoute<ExampleTestRouteData>,
// all generic types are defaulting to angular standard types
) { }
}
and template:
<div>{{ route.snapshot.data.exampleResponse.id }}</div>
<div>{{ route.snapshot.data.exampleResponse.name }}</div>
All is type-safe and refactorable.
Check the documentation for more examples.
回答3:
Extrapolating on Madhu's answer, if you want your entire navigation tree to have those properties, not just the top level routes, you must also override the children
property like this:
interface CustomRoute extends Route {
data?: RouteData;
children?: CustomRoute[];
}
I had a similar approach to Madhu's but was wondering why my child routes did not have intellisense or type safety. Then I realized the children
property was still set to Routes
from the framework's definition.
来源:https://stackoverflow.com/questions/47175065/passing-type-safe-route-data-to-routes-in-angular-2