我有以下路由配置。
@RouteConfig([
{
path: '/home',
name: 'Homepage',
component: HomepageComponent,
useAsDefault: true
}
)
export class AppComponent {
}
每当浏览器指向/home
时此路由有效,但不适用于/Home
或任何其他案例变体。如何在不关心案例的情况下使路由器路由到组件。
感谢
答案 0 :(得分:34)
这就是我的所作所为。
import { DefaultUrlSerializer, UrlTree } from '@angular/router';
export class LowerCaseUrlSerializer extends DefaultUrlSerializer {
parse(url: string): UrlTree {
// Optional Step: Do some stuff with the url if needed.
// If you lower it in the optional step
// you don't need to use "toLowerCase"
// when you pass it down to the next function
return super.parse(url.toLowerCase());
}
}
和
@NgModule({
imports: [
...
],
declarations: [AppComponent],
providers: [
{
provide: UrlSerializer,
useClass: LowerCaseUrlSerializer
}
],
bootstrap: [AppComponent]
})
答案 1 :(得分:8)
<强>更新强>
这还没有进入新的路由器
<强>原始强>
最近推出了正则表达式匹配器。这可能对您的用例有所帮助。
请参阅https://github.com/angular/angular/pull/7332/files
来自Brandon Roberts的Plunker
@RouteConfig([
{ name : 'Test',
//path : '/test',
regex: '^(.+)/(.+)$',
serializer: (params) => new GeneratedUrl(`/${params.a}/${params.b}`, {c: params.c}),
component: Test
// useAsDefault: true
}
])
答案 2 :(得分:7)
我在app.component.ts中执行了此操作:
export class AppComponent implements OnInit {
constructor(private _route: Router) { }
public ngOnInit() {
this._route.events.subscribe(event => {
if (event instanceof NavigationStart) {
let url = (<NavigationStart>event).url;
if (url !== url.toLowerCase()) {
this._route.navigateByUrl((<NavigationStart>event).url.toLowerCase());
}
}
});
}
}
并且在路由器链接上需要这个以使其在选中时处于活动状态:
<a routerLink="/heroes" routerLinkActive="active" [routerLinkActiveOptions]="{ exact: false }">Heroes</a>
答案 3 :(得分:7)
对Timothy's answer的一点修复,它不会改变匹配的参数名称和值的大小写:
class A(object):
a = "Hello"
b = "World"
class B(A):
pass
class C(B):
pass
c = C()
print(c.a,c.b)
编辑:除了上面解释的问题之外,还有另一个微妙的错误,现在已经解决了。 for循环应该迭代import {Route, UrlSegment, UrlSegmentGroup} from '@angular/router';
export function caseInsensitiveMatcher(url: string) {
return function(
segments: UrlSegment[],
segmentGroup: UrlSegmentGroup,
route: Route
) {
const matchSegments = url.split('/');
if (
matchSegments.length > segments.length ||
(matchSegments.length !== segments.length && route.pathMatch === 'full')
) {
return null;
}
const consumed: UrlSegment[] = [];
const posParams: {[name: string]: UrlSegment} = {};
for (let index = 0; index < matchSegments.length; ++index) {
const segment = segments[index].toString().toLowerCase();
const matchSegment = matchSegments[index];
if (matchSegment.startsWith(':')) {
posParams[matchSegment.slice(1)] = segments[index];
consumed.push(segments[index]);
} else if (segment.toLowerCase() === matchSegment.toLowerCase()) {
consumed.push(segments[index]);
} else {
return null;
}
}
return { consumed, posParams };
};
}
而不是matchSegments
。
答案 4 :(得分:5)
注意:以下适用于Angular 4.x
我只使用匹配功能:
import { RouterModule, UrlSegment, UrlSegmentGroup, Route } from '@angular/router';
function CaseInsensitiveMatcher(url: string) {
url = url.toLowerCase();
return function(
segments: UrlSegment[],
segmentGroup: UrlSegmentGroup,
route: Route
) {
let matchSegments = url.split('/');
if (
matchSegments.length > segments.length ||
(matchSegments.length !== segments.length && route.pathMatch === 'full')
) {
return null;
}
let consumed: UrlSegment[] = [];
let posParams: {[name: string]: UrlSegment} = {};
for (let index = 0; index < segments.length; ++index) {
let segment = segments[index].toString().toLowerCase();
let matchSegment = matchSegments[index];
if (matchSegment.startsWith(':')) {
posParams[matchSegment.slice(1)] = segments[index];
consumed.push(segments[index]);
}
else if (segment === matchSegment) {
consumed.push(segments[index]);
}
else {
return null;
}
}
return { consumed, posParams };
}
}
使用:
@NgModule({
imports: [
...
RouterModule.forRoot([
{ matcher: CaseInsensitiveMatcher('user/:id'), component: ProfileComponent },
])
],
declarations: [
...
],
bootstrap: [
AppComponent
]
})
编辑:我刚刚发现,为了使用AoT编译,@ NgModule部分看起来更像是这样:
export function profileMatch() {
return CaseInsensitiveMatcher('user/:id').apply(this, arguments);
}
@NgModule({
imports: [
...
RouterModule.forRoot([
{ matcher: profileMatch, component: ProfileComponent },
])
],
declarations: [
...
],
bootstrap: [
AppComponent
]
})
答案 5 :(得分:2)
我对此问题的解决方法:
/* IMPORTS */
let routeEntries = [
{ path: '/home', component: HomePage }
/* DEFAULT ROUTE */
{ path: '/', component: HomePage },
/* NOT FOUND ROUTE */
{ path: '*', component: HomePage }
];
@Component(/* SETUP */)
@Routes(routeEntries)
export App implements OnInit {
/* STUFF */
ngOnInit() {
// subscribe to router changes
this.router.changes.forEach(() => {
let routerLink = location.pathname;
let routerLinkLower = routerLink.toLowerCase();
// if the route does not exist, check for the lowercase version
if (!routeEntries.find((route) => { return route.path === routerLink; })) {
this.router.navigate([routerLinkLower]);
}
// if the route is correct, set the active page
else {
// do something here if required
}
});
}
}
这适用于RC1路由器,并与路线变化相符,例如:
'{domain}:{port}/HoMe'
'{domain}:{port}/homE'
'{domain}:{port}/Home'
...
答案 6 :(得分:0)
这里是LowerCaseUrlSerializer
的更新版本,不小写查询参数。
import { DefaultUrlSerializer, UrlTree } from '@angular/router';
export class LowerCaseUrlSerializer extends DefaultUrlSerializer {
parse(url: string): UrlTree {
const path = url.split('?')[0];
const query = url.split('?')[1] || '';
return super.parse(path.toLowerCase() + (query !== '' ? `?${query}`: ''));
}
}
答案 7 :(得分:-4)
这就是我解决这个问题的方法
{ path: '/home', redirectTo: ['/Home'] },
{ path: '/Home', component: HomeComponent, name: 'Home' },