Angular2: Сделать дорожки нечувствительными к регистру
У меня есть следующая конфигурация маршрутизации.
@RouteConfig([ { path: '/home', name: 'Homepage', component: HomepageComponent, useAsDefault: true } ) export class AppComponent { }
всякий раз, когда браузер указывает на /home
этот маршрут работает, но не для /Home
или любых других вариантов случая. Как я могу сделать маршрутизатор для маршрутизации к компоненту, не заботясь о случае.
благодаря
- Угловой 2.0 маршрутизатор не работает при перезагрузке браузера
- Использование разрешения в Angular2 Routes
- Как получить текущий маршрут
- Предупреждать пользователя о несохраненных изменениях перед выходом на страницу
- Маршрут Angular 2's Router нарушен при использовании маршрутов HTML5?
- Как передать параметры запроса с помощью routerLink в новом Router V 3 alpha (владивосток)
- Страница обновления Angular2 router.navigate обновить
- Как определить, как пользователь перемещается обратно в Angular2?
- Как переключать макеты в Angular2
- Как использовать HashLocationStrategy с виджем Auth0 Lock для входа пользователя
- Угловой маршрутизатор поддерживает строку запроса
- Угловое redirect на страницу входа в систему
- Угловая ошибка 2: 404 возникает при обновлении через браузер
Вот что я сделал.
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] })
Обновить
Это еще не дошло до нового маршрутизатора
оригинал
Недавно были введены регулярные выражения. Это может помочь в вашем случае использования.
См. https://github.com/angular/angular/pull/7332/files
И этот Plunker от Брэндона Робертса
@RouteConfig([ { name : 'Test', //path : '/test', regex: '^(.+)/(.+)$', serializer: (params) => new GeneratedUrl(`/${params.a}/${params.b}`, {c: params.c}), component: Test // useAsDefault: true } ])
Я сделал это в своем 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 = (event).url; if (url !== url.toLowerCase()) { this._route.navigateByUrl(( event).url.toLowerCase()); } } }); } }
и это необходимо для маршрутизатора-ссылки, чтобы сделать его активным при выборе:
Heroes
Примечание. В 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 ] })
Мое обходное решение для этой проблемы:
/* 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' ...
Немного исправить ответ Тимоти , который не меняет случай совпадающих имен параметров и значений:
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 }; }; }
Изменить : помимо проблемы, описанной выше, есть еще одна тонкая ошибка, которая теперь устранена. Цикл for должен перебирать matchSegments
вместо segments
.
Вот как я исправил эту проблему
{ path: '/home', redirectTo: ['/Home'] }, { path: '/Home', component: HomeComponent, name: 'Home' },