将类型安全的路由数据传递给 angular 中的路由 2

Passing type-safe route data to routes in angular 2

在我的路由模块中,我以这种方式传递数据。

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);

为了使数据类型安全,我创建了一个 RouteData class 来保存 ShowTopBarShowSideBar 值并通过构造函数初始化它们。

export class RouteData {
constructor(showTopbar: boolean, showSideBar: boolean) {
  this.ShowSideBar = showSideBar;
  this.ShowTopBar = showTopbar;
}
 public ShowTopBar: boolean;
 public ShowSideBar: boolean;
}

现在,我按以下方式更改了路由声明:

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)}

];

编译时出现以下错误:

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

我的问题是我们如何以类型安全的方式将 RouteData 传递给路由,以便我可以利用类型安全。

你可以在下面做,

@angular/router 扩展路线并更新数据类型,如下所示,

export interface RouteData {
  ShowTopBar: boolean;
  ShowSideBar: boolean;
}

interface CustomRoute extends Route {
  data?: RouteData;
}

将路由类型从 Routes

更新为 CustomRoute[]
const routes: CustomRoute[] = [
  { path: '', redirectTo: '/home', pathMatch: 'full' },
  { path: 'home', component: HomeComponent, data: { ShowSideBar: true, ShowTopBar: true } }
];

现在你可以传递类型安全的数据,见下文,

我编写了一个涵盖标准路由器所有类型的小型库。

ngx-typed-router

它允许您拥有从路由器配置、组件、解析器到测试结束的所有内容的类型。

例如

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({
  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
  ) { }

}

和模板:

<div>{{ route.snapshot.data.exampleResponse.id }}</div>
<div>{{ route.snapshot.data.exampleResponse.name }}</div>

所有内容都是类型安全且可重构的。

查看文档以获取更多示例。

根据 Madhu 的回答推断,如果您希望 entire 导航树具有这些属性,而不仅仅是 top 级路由,您还必须像这样覆盖 children 属性:

interface CustomRoute extends Route {
  data?: RouteData;
  children?: CustomRoute[];
}

我采用了与 Madhu 类似的方法,但想知道为什么我的子路由没有智能感知或类型安全。然后我意识到框架定义中的 children 属性 仍然设置为 Routes