Angular 4 路由:是否可以给路由参数加约束?
Angular 4 routing: Is it possible to add constraints to route parameters?
我想在我的路由服务中匹配一种语言。
我的问题是语言需要在我的路线中排在第一位。
例如:
/en/xxx
/fr/xxx
/en/yyy
/fr/yyy
因为我想使用这个参数,所以我添加了以下路由
{ path: ':lang', children: [
{path: '', redirectTo: 'xxx', pathMatch: 'full'},
{path: 'xxx', component: x},
{path: 'yyy', component: y}
]}
问题是一切都匹配 :lang。
例如:
/abc/xxx
我想对此添加约束,这样我就可以说 :lang 只能是类型 <'nl' | 'fr' | 'en' | 'de'>.
现在,当我想转到 /robots.txt(应该显示 robots.txt 文件)时,它映射到 :lang 并将我发送到“/robots.txt/xxx”
我已经尝试分别映射每种语言,但我无法访问路由参数。
我试过在上面添加 robots.txt 但由于它是一个资产文件,我不知道如何通过在 routes.ts 文件中添加一行来显示它。
我试过在路由守卫中添加一个例外,但后来我无法重定向到 robots.txt,因为它只是在 :lang 参数上保持映射。
这是我当前的 routes.ts 文件:
{path: '', redirectTo: '/xxx', pathMatch: 'full', canActivate: [LangGuard]},
{path: 'xxx', component: xxx, canActivate: [LangGuard]},
{path: 'yyy', component: yyy, canActivate: [LangGuard]},
{ path: ':lang', canActivate: [LangGuard], children: [
{path: '', redirectTo: 'xxx', pathMatch: 'full'},
{path: 'xxx', component: x},
{path: 'yyy', component: y}
]}
我的 LangGuard 非常广泛,但我会写一个简短的版本:
Get route parameters
If parameter is "nl", "fr", "de" or "en"
then return true //do nothing
else router.navigate('/' + decideLanguage() + state.url) // redirect to new url
大概概述一下我想要实现的目标和我得到的目标:
我想要什么
/ -> /en/xxx
/abc -> /en/xxx
/xxx -> /en/xxx
/yyy -> /en/yyy
/en/xxx -> ok
/fr/xxx -> ok
/de/xxx -> ok
/en/abc -> notfound
/abc/xxx -> notfound
/abc/yyy -> notfound
/robots.txt -> ok
我有什么
/ -> /en/xxx
/abc -> /en/xxx
/xxx -> /en/xxx
/yyy -> /en/yyy
/en/xxx -> ok
/fr/xxx -> ok
/de/xxx -> ok
/en/abc -> notfound
/abc/xxx -> ok (WRONG)
/abc/yyy -> ok (WRONG)
/robots.txt -> /robots.txt/xxx (WRONG)
注意:我不能使用 redirectTo 作为语言,因为语言是根据本地存储选择的,这就是我使用 routeguard
的原因
如果我需要添加更多信息或者您有任何问题,请随时提出,我会尽我所能回答。
谢谢
您可以使用 canActivate
守卫并使用它以编程方式确定 lang
路由参数是您提到的四种语言之一。
我会尝试 Angular UrlMatcher
.有了它,您可以定义自己的 url 匹配函数。恕我直言,警卫更多的是为了检查身份验证,而不是检查路由是否有效。
举个例子:
路由
export function checkLang(url: UrlSegment[]) {
return url[0].path.startsWith('en') || url[0].path.startsWith('fr') || url[0].path.startsWith('de') || url[0].path.startsWith('nl') ? ({consumed: url}) : null;
}
export const routes = [ matcher: checkLang, component: TestComponent, children: [
{path: '', redirectTo: 'xxx', pathMatch: 'full'},
{path: 'xxx', component: x},
{path: 'yyy', component: y}
]}]
然后是 TestComponent
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
@Component({
selector: 'app-test',
template: '<div>HELLO</div>'
})
export class TestComponent implements OnInit {
constructor(
public route: ActivatedRoute,
public router: Router
) { }
ngOnInit() {
console.log('LANGUAGE: ' + this.route.snapshot.url[0].path); // here you get the language and you can act consequently
}
}
选择的答案就是为了这个目的,值得一提的是,如果有人有一个自定义组件用于找不到语言,例如,这就不够灵活。除非它既可靠又可能从我怀疑的匹配功能内部导航。我认为在那种情况下,理想的做法是拥有一个容器组件来进行检查,否则导航匹配 :lang,其余组件作为子组件加载。
路由
{
path: ':lang',
component: LanguageContainerComponent,
children: [
{
{ path: '', redirectTo: 'xxx', pathMatch: 'full' },
{ path: 'xxx', component: x },
{ path: 'yyy', component: y }
}
]
},
{ path: 'languagenotfound', component: LanguageNotFoundComponent },
组件
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
@Component({
selector: 'app-language-container',
template: '<router-outlet></router-outlet>'
})
export class LanguageContainerComponent implements OnInit {
constructor(
public route: ActivatedRoute,
public router: Router
) { }
ngOnInit() {
// Do your checks here
// if fail
this.router.navigate(['languagenotfound']);
}
}
如果您使用的是 ngx-translate 之类的库,则可以注入
private translate: TranslateService
并使用
this.translate.getLangs().includes(langParam)
因为我不认为你可以在 UrlMatcher 中注入服务
我想在我的路由服务中匹配一种语言。 我的问题是语言需要在我的路线中排在第一位。
例如:
/en/xxx
/fr/xxx
/en/yyy
/fr/yyy
因为我想使用这个参数,所以我添加了以下路由
{ path: ':lang', children: [
{path: '', redirectTo: 'xxx', pathMatch: 'full'},
{path: 'xxx', component: x},
{path: 'yyy', component: y}
]}
问题是一切都匹配 :lang。
例如:
/abc/xxx
我想对此添加约束,这样我就可以说 :lang 只能是类型 <'nl' | 'fr' | 'en' | 'de'>.
现在,当我想转到 /robots.txt(应该显示 robots.txt 文件)时,它映射到 :lang 并将我发送到“/robots.txt/xxx”
我已经尝试分别映射每种语言,但我无法访问路由参数。
我试过在上面添加 robots.txt 但由于它是一个资产文件,我不知道如何通过在 routes.ts 文件中添加一行来显示它。
我试过在路由守卫中添加一个例外,但后来我无法重定向到 robots.txt,因为它只是在 :lang 参数上保持映射。
这是我当前的 routes.ts 文件:
{path: '', redirectTo: '/xxx', pathMatch: 'full', canActivate: [LangGuard]},
{path: 'xxx', component: xxx, canActivate: [LangGuard]},
{path: 'yyy', component: yyy, canActivate: [LangGuard]},
{ path: ':lang', canActivate: [LangGuard], children: [
{path: '', redirectTo: 'xxx', pathMatch: 'full'},
{path: 'xxx', component: x},
{path: 'yyy', component: y}
]}
我的 LangGuard 非常广泛,但我会写一个简短的版本:
Get route parameters
If parameter is "nl", "fr", "de" or "en"
then return true //do nothing
else router.navigate('/' + decideLanguage() + state.url) // redirect to new url
大概概述一下我想要实现的目标和我得到的目标:
我想要什么
/ -> /en/xxx
/abc -> /en/xxx
/xxx -> /en/xxx
/yyy -> /en/yyy
/en/xxx -> ok
/fr/xxx -> ok
/de/xxx -> ok
/en/abc -> notfound
/abc/xxx -> notfound
/abc/yyy -> notfound
/robots.txt -> ok
我有什么
/ -> /en/xxx
/abc -> /en/xxx
/xxx -> /en/xxx
/yyy -> /en/yyy
/en/xxx -> ok
/fr/xxx -> ok
/de/xxx -> ok
/en/abc -> notfound
/abc/xxx -> ok (WRONG)
/abc/yyy -> ok (WRONG)
/robots.txt -> /robots.txt/xxx (WRONG)
注意:我不能使用 redirectTo 作为语言,因为语言是根据本地存储选择的,这就是我使用 routeguard
的原因如果我需要添加更多信息或者您有任何问题,请随时提出,我会尽我所能回答。
谢谢
您可以使用 canActivate
守卫并使用它以编程方式确定 lang
路由参数是您提到的四种语言之一。
我会尝试 Angular UrlMatcher .有了它,您可以定义自己的 url 匹配函数。恕我直言,警卫更多的是为了检查身份验证,而不是检查路由是否有效。
举个例子:
路由
export function checkLang(url: UrlSegment[]) {
return url[0].path.startsWith('en') || url[0].path.startsWith('fr') || url[0].path.startsWith('de') || url[0].path.startsWith('nl') ? ({consumed: url}) : null;
}
export const routes = [ matcher: checkLang, component: TestComponent, children: [
{path: '', redirectTo: 'xxx', pathMatch: 'full'},
{path: 'xxx', component: x},
{path: 'yyy', component: y}
]}]
然后是 TestComponent
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
@Component({
selector: 'app-test',
template: '<div>HELLO</div>'
})
export class TestComponent implements OnInit {
constructor(
public route: ActivatedRoute,
public router: Router
) { }
ngOnInit() {
console.log('LANGUAGE: ' + this.route.snapshot.url[0].path); // here you get the language and you can act consequently
}
}
选择的答案就是为了这个目的,值得一提的是,如果有人有一个自定义组件用于找不到语言,例如,这就不够灵活。除非它既可靠又可能从我怀疑的匹配功能内部导航。我认为在那种情况下,理想的做法是拥有一个容器组件来进行检查,否则导航匹配 :lang,其余组件作为子组件加载。
路由
{
path: ':lang',
component: LanguageContainerComponent,
children: [
{
{ path: '', redirectTo: 'xxx', pathMatch: 'full' },
{ path: 'xxx', component: x },
{ path: 'yyy', component: y }
}
]
},
{ path: 'languagenotfound', component: LanguageNotFoundComponent },
组件
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
@Component({
selector: 'app-language-container',
template: '<router-outlet></router-outlet>'
})
export class LanguageContainerComponent implements OnInit {
constructor(
public route: ActivatedRoute,
public router: Router
) { }
ngOnInit() {
// Do your checks here
// if fail
this.router.navigate(['languagenotfound']);
}
}
如果您使用的是 ngx-translate 之类的库,则可以注入
private translate: TranslateService
并使用
this.translate.getLangs().includes(langParam)
因为我不认为你可以在 UrlMatcher 中注入服务