AoT 和函数工厂(动态路由模板)
AoT and function factory (Dynamic Route Templates)
我正在尝试建立一个 UrlMatcher 工厂
export const dummyMatcher: UrlMatcher = matchUrlFn(sitemap as any, 'dummy');
export const routes: Routes = [
{ matcher: dummyMatcher, component: DummyComponent },
{ path: '**', component: DummyComponent },
];
但这不适用于 AoT...我们如何使用 AoT 处理函数工厂?
我试过了
export function dummyMatcher(): UrlMatcher { return routeMatcher(sitemap as any, 'dummy'); }
但是编译器在抱怨:
Type '{ matcher: () => UrlMatcher; component: typeof DummyComponent; }...' is not assignable to type 'Route[]'.
用例:
我需要匹配网页(在 NavigationNode[]
中描述)并在特定的模板组件中呈现它们。页面可以有多个 url(用于迁移目的、本地化 url 等)。
匹配逻辑如下:
import { UrlSegment, UrlSegmentGroup, Route, UrlMatchResult } from '@angular/router';
import { inArray } from '@core/utils';
export interface NavigationNode {
...
title?: string;
template?: string;
urls?: string[];
}
/**
* https://angular.io/api/router/UrlMatcher
*/
export const UrlMatcherFactory = (conditions) =>
(segments: UrlSegment[], group: UrlSegmentGroup, route: Route): UrlMatchResult =>
conditions(segments) ? ({ consumed: segments }) : null;
export const matchUrl = (nodes: NavigationNode[], template?: string) =>
(segments: UrlSegment[]) => nodes
.filter(node => template ? node.template === template : true)
.some(node => inArray(node.urls)(`/${segments.join('/')}`));
export const matchUrlFn= (nodes: NavigationNode[], template?: string) =>
UrlMatcherFactory(matchUrl(nodes, template));
这可以很容易地扩展到使用不同的匹配,例如正则表达式:
export const matchRegex = (nodes: NavigationNode[]) =>
(segments: UrlSegment[]) => nodes
.some(node => /\w+\/xyz/\d{1, 3}/.test(node.title)); /* bad example (: */
export const matchRegexFn = (nodes: NavigationNode[], template?: string) =>
UrlMatcherFactory(matchRegex(nodes));
matcher
属性 应该实现 UrlMatcher
类型:
export declare type UrlMatcher = (segments: UrlSegment[], group: UrlSegmentGroup, route: Route) => UrlMatchResult;
所以我建议您更改代码,例如:
export function dummyMatcher(segments: UrlSegment[], group: UrlSegmentGroup, route: Route): UrlMatchResult {
const factory = matchUrlFn(sitemap as any, 'dummy');
return factory(segments, group, route);
}
对于面临 AOT 编译器问题的新手
你需要将 fat arrow 函数移动到普通的 ES5 函数 & export
它(即使你不在其他任何地方使用它)
移动这个
const routes: Routes = [
{
component: SomeComponent,
matcher: () => { //your url matcher },
}
,...
];
至
export function yourUrlMatcher( //params ) { //your function here }
const routes: Routes = [
{
component: SomeComponent,
matcher: yourUrlMatcher,
}
,...
];
我正在尝试建立一个 UrlMatcher 工厂
export const dummyMatcher: UrlMatcher = matchUrlFn(sitemap as any, 'dummy');
export const routes: Routes = [
{ matcher: dummyMatcher, component: DummyComponent },
{ path: '**', component: DummyComponent },
];
但这不适用于 AoT...我们如何使用 AoT 处理函数工厂?
我试过了
export function dummyMatcher(): UrlMatcher { return routeMatcher(sitemap as any, 'dummy'); }
但是编译器在抱怨:
Type '{ matcher: () => UrlMatcher; component: typeof DummyComponent; }...' is not assignable to type 'Route[]'.
用例:
我需要匹配网页(在 NavigationNode[]
中描述)并在特定的模板组件中呈现它们。页面可以有多个 url(用于迁移目的、本地化 url 等)。
匹配逻辑如下:
import { UrlSegment, UrlSegmentGroup, Route, UrlMatchResult } from '@angular/router';
import { inArray } from '@core/utils';
export interface NavigationNode {
...
title?: string;
template?: string;
urls?: string[];
}
/**
* https://angular.io/api/router/UrlMatcher
*/
export const UrlMatcherFactory = (conditions) =>
(segments: UrlSegment[], group: UrlSegmentGroup, route: Route): UrlMatchResult =>
conditions(segments) ? ({ consumed: segments }) : null;
export const matchUrl = (nodes: NavigationNode[], template?: string) =>
(segments: UrlSegment[]) => nodes
.filter(node => template ? node.template === template : true)
.some(node => inArray(node.urls)(`/${segments.join('/')}`));
export const matchUrlFn= (nodes: NavigationNode[], template?: string) =>
UrlMatcherFactory(matchUrl(nodes, template));
这可以很容易地扩展到使用不同的匹配,例如正则表达式:
export const matchRegex = (nodes: NavigationNode[]) =>
(segments: UrlSegment[]) => nodes
.some(node => /\w+\/xyz/\d{1, 3}/.test(node.title)); /* bad example (: */
export const matchRegexFn = (nodes: NavigationNode[], template?: string) =>
UrlMatcherFactory(matchRegex(nodes));
matcher
属性 应该实现 UrlMatcher
类型:
export declare type UrlMatcher = (segments: UrlSegment[], group: UrlSegmentGroup, route: Route) => UrlMatchResult;
所以我建议您更改代码,例如:
export function dummyMatcher(segments: UrlSegment[], group: UrlSegmentGroup, route: Route): UrlMatchResult {
const factory = matchUrlFn(sitemap as any, 'dummy');
return factory(segments, group, route);
}
对于面临 AOT 编译器问题的新手
你需要将 fat arrow 函数移动到普通的 ES5 函数 & export
它(即使你不在其他任何地方使用它)
移动这个
const routes: Routes = [
{
component: SomeComponent,
matcher: () => { //your url matcher },
}
,...
];
至
export function yourUrlMatcher( //params ) { //your function here }
const routes: Routes = [
{
component: SomeComponent,
matcher: yourUrlMatcher,
}
,...
];