Javascript CanActivate,动态URL的解析程序(多个嵌套的动态段)
我构建了一个web应用程序,其中包含dynamicly生成的大部分页面。(99%). 每个页面只是一个带有空模板的组件,其中所有数据都是通过url的slug从multiples services API提供的 url可以包含三个嵌套级别,每个级别都必须对应一个逻辑嵌套(从上下文的角度来看,我的意思是…友好) 例如,显示国家信息的应用程序:Javascript CanActivate,动态URL的解析程序(多个嵌套的动态段),javascript,angularjs,angular,nested,angular2-routing,Javascript,Angularjs,Angular,Nested,Angular2 Routing,我构建了一个web应用程序,其中包含dynamicly生成的大部分页面。(99%). 每个页面只是一个带有空模板的组件,其中所有数据都是通过url的slug从multiples services API提供的 url可以包含三个嵌套级别,每个级别都必须对应一个逻辑嵌套(从上下文的角度来看,我的意思是…友好) 例如,显示国家信息的应用程序: 地区- 县- 城市- url使用的每个标记名都必须转换为有效的重叠名称:如俄罗斯玩偶 路由器似乎是这样的: { path: ':region-sl
路由器似乎是这样的:
{
path: ':region-slug',
component: RegionComponent,
resolve: {
region: RegionResolver
}
},
{
path: ':region-slug/:countie-slug',
component: CountieComponent,
resolve: {
departement: CountieResolver
}
},
{
path: ':region-slug/:countie-slug/:city-slug',
component: CityComponent,
resolve: {
region: CityResolver
}
}
第一个问题,url可以是任何内容,它总是正确的:
@Injectable()
导出类RegionResolver实现Resolve=>true
从我所看到的情况来看,您几乎做到了:您的路线声明和解决方案似乎很好 如果段塞无效,为什么不从解析中验证段塞并重定向到
/404
您可以创建如下函数:
// validate-slugs.ts
/**
* Return true if all given slugs are valid.
*/
export function are_slugs_valid(slugs: any): boolean {
const validRegions = ['ile-de-france', 'nord-pas-de-calais'];
const validCounties = ['val-de-marne', 'nord', 'pas-de-calais'];
// Validate region slug
if (slugs && slugs['region-slug'] && validRegions.indexOf(slugs['region-slug']) === -1) {
return false;
}
// Validate county slug
if (slugs && slugs['county-slug'] && validCounties.indexOf(slugs['county-slug']) === -1) {
return false;
}
// @TODO: Validate city slug...
return true;
}
然后在你的决议中使用它,如下所示:
@Injectable()
export class RegionResolver implements Resolve<any>{
constructor(private router: Router) { }
resolve(route: ActivatedRouteSnapshot): Observable<any> {
// NB. route.params contains ALL the slugs in the current route.
if (!are_slugs_valid(route.params)) {
this.router.navigate(['/404']);
}
// Proceed with fetching additional data...
}
}
这样,对于最深的路径,如法兰西岛/val de marne/creteil,您只需要一个查询来验证路径中包含的三个slug(:区域slug
,:县slug
,和:城市slug
)
2) 如果将path
列添加到存储实体(即地区、县、市…)的同一个表中,则只需一个查询即可加载实体并验证路径(路径充当实体的键)
旁注:如果您遵循我上面的建议,将代码保存在解析中是有意义的,因为它预加载了一些数据并进行了一些验证,这就是解析的目的。如果您只是想在不预加载数据的情况下验证路径,我可能会将代码放在CanActivate
服务中
// validate-slugs.ts
/**
* Return true if all given slugs are valid.
*/
export function are_slugs_valid(slugs: any): boolean {
const validRegions = ['ile-de-france', 'nord-pas-de-calais'];
const validCounties = ['val-de-marne', 'nord', 'pas-de-calais'];
// Validate region slug
if (slugs && slugs['region-slug'] && validRegions.indexOf(slugs['region-slug']) === -1) {
return false;
}
// Validate county slug
if (slugs && slugs['county-slug'] && validCounties.indexOf(slugs['county-slug']) === -1) {
return false;
}
// @TODO: Validate city slug...
return true;
}
@Injectable()
export class RegionResolver implements Resolve<any>{
constructor(private router: Router) { }
resolve(route: ActivatedRouteSnapshot): Observable<any> {
// NB. route.params contains ALL the slugs in the current route.
if (!are_slugs_valid(route.params)) {
this.router.navigate(['/404']);
}
// Proceed with fetching additional data...
}
}
ile-de-france
ile-de-france/val-de-marne
ile-de-france/val-de-marne/creteil
...