[英]Angular 5 - ngx-translate within routerLink
在我的項目(Angular 5 + Firebase)中,用戶需要在登錄頁面上選擇語言。 為此,我添加了選擇選項,並將選定的值作為參數傳遞給第一頁,如下所示:
form_login(f:NgForm){
if (!f.valid)
return;
this.afAuth.auth.signInWithEmailAndPassword(f.controls.email.value, f.controls.password.value)
.then(ok => {
this.router.navigate(["/perfil", f.controls.lang.value]); //>> here
});
}
在網址中包含此參數后,我將檢索此值並使用ngx-translate來翻譯整個頁面,如下所示:
perfil.component.ts
import { Router, ActivatedRoute, ParamMap } from '@angular/router';
import { TranslateService } from '@ngx-translate/core';
constructor(private translate: TranslateService,
private route: ActivatedRoute,
private router: Router) {
...
translate.setDefaultLang('en');
let lang = this.route.snapshot.paramMap.get('lang');
this.translate.use(lang);
console.log(lang);
}
perfil.component.html
<h5 translate>Companyprofile</h5>
完美的作品。 除外,因為還有導航欄,並且此組件根本無法獲得語言值。 盡管翻譯了鏈接標簽,但是每個routerLink
的值都沒有捕獲參數的值,而是將每個鏈接設置為undefined
,而該語言的值應該在該位置。
navbar.component.ts
import { Router, ActivatedRoute, ParamMap } from '@angular/router';
import { TranslateService } from '@ngx-translate/core';
constructor(private translate: TranslateService,
private route: ActivatedRoute,
private router: Router) {
...
translate.setDefaultLang('en');
let lang = this.route.snapshot.paramMap.get('lang');
this.translate.use(lang);
console.log(lang); // >> in this case, the console displays `null`
}
試圖在navbar.component.ts上也獲得此值,我在控制台上遇到此錯誤:
navbar.component.ts:36 null
zone.js:2935 GET http://localhost:4200/assets/i18n/null.json 404 (Not Found)
core.js:1440 ERROR HttpErrorResponse {headers: HttpHeaders, status: 404, statusText: "Not Found", url: "http://localhost:4200/assets/i18n/null.json", ok: false, …}
navbar.component.html
<header id="topnav">
<ul class="navbar-nav" *ngFor="let p of perfil | async">
<li class="nav-item">
<a [routerLink]="['/agenda/', lang]" class="nav-link" translate>Agenda</a>
</li>
<li class="nav-item">
<a [routerLink]="['/admin/', lang]" class="nav-link" translate>Admin</a>
</li>
...
</ul>
</header>
<router-outlet></router-outlet> <!-- here I call other components, e.g perfil.component.html
例如, lang
參數應帶值'en' 。 但是,它是undefined
。
編輯:我所有的組件都是NavbarComponent
子NavbarComponent
。 NavbarComponent
沒有path
,因此無法像在其他路徑中那樣在其上設置參數。
app.routing.module.ts
const AppRoutes: Routes = [
{path: '', component: AppComponent, children: [
{ path: '', redirectTo: '/login', pathMatch: 'full' },
{path: '', component: NavbarComponent, children: [
{path: 'agenda/:lang', component: AgendaComponent},
{path: 'perfil/:lang', component: PerfilComponent},
{path: 'servicos/:lang', component: CadastroServicoComponent},
{path: 'profissionais/:lang', component: ProfissionaisComponent},
{path: 'admin/:lang', component: AdminComponent},
{path: 'dashboard/:lang', component: DashboardComponent},
{path: 'signup/:lang', component: SignUpFormComponent}
]}
]}
]
@NgModule({
imports: [RouterModule.forRoot(AppRoutes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
代碼有什么問題?
好了,這是根據我從代碼中看到的建議。
您的導航欄可能在一個組件中被稱為子組件,在perfil.component.html
可能像這樣。
<navbar [parameters...]></navbar>
我對此不是100%的確定,但我猜想ActivatedRoute
注入僅適用於通過直接路由器鏈接加載的組件,而不適用於子模塊(我對此不確定)。 這意味着, AcitvatedRoute
作品為perfil.component
但不能用於navbar.component
(因為不是從你的路由器的稱呼)。 但是,如果像上面顯示的那樣調用導航欄,則可以將perfil.component
的lang
變量作為輸入參數發送到導航欄。
這是perfil.component.html
:
<navbar [lang]="lang"></navbar>
這是navbar.component.ts
:
// the lang string is now an input parameter
@Input() lang: string;
constructor(private translate: TranslateService, private router: Router) {
...
// the default language should already been set in the parent component
// NO NEED: translate.setDefaultLang('en');
}
// the input parameter are not yet availbable in the constructor, but on init
ngOnInit(){
this.translate.use(lang);
console.log(lang);
}
希望這可以幫助。
看到您的命令后,我看到導航欄出現了問題。 您的導航欄組件是第一個被調用的組件,可以說是父組件,它是在初始化子組件之前建立的。
問題在於導航欄有其自己的當前路徑。 您想要做的是訪問父組件中的子路由。 我在這里找到了一個類似的問題,答案似乎已經不再有效。 您可以檢查是否有必要,盡管看起來有些棘手,但還有另一種解決方案。 因此,我不確定這是否可行。
我看到的問題是該方法本身將語言作為子組件而不是父組件的路由參數。 該語言當前是在導航欄的每個子路徑上設置的路徑參數,導致代碼中的重復很多。 無論如何,所有孩子絕對必須經歷導航欄初始化過程,那么為什么不在那里處理語言呢? 這樣,您只需要在代碼中的一個位置進行語言加載即可。
在這種情況下,您可能必須調整路由器。
{ path: '', redirectTo: '/login', pathMatch: 'full' },
{ path: ':lang', component: NavbarComponent, children: [
{path: 'agenda', component: AgendaComponent},
{path: 'perfil', component: PerfilComponent},
{path: 'servicos', component: CadastroServicoComponent},
{path: 'profissionais', component: ProfissionaisComponent},
{path: 'admin', component: AdminComponent},
{path: 'dashboard', component: DashboardComponent},
{path: 'signup', component: SignUpFormComponent}
]}
另外,不再需要當前不起作用的代碼,因為您不必再將語言提供給子路由。
<header id="topnav">
<ul class="navbar-nav" *ngFor="let p of perfil | async">
<li class="nav-item">
<!-- without / the router routes to children relative to the current path -->
<!-- no need for the language anymore -->
<a [routerLink]="['agenda']" class="nav-link" translate>Agenda</a>
</li>
<li class="nav-item">
<a [routerLink]="['admin']" class="nav-link" translate>Admin</a>
</li>
...
</ul>
</header>
從您的登錄頁面,您直接路由到/lang
頁面(即導航欄),然后在那里初始化語言(並且只執行一次)。 現在,所有子組件都是lang
路由的子組件,而不是擁有自己的lang
參數。 在navbar.component.ts
您可能會使用與當前使用的完全相同的代碼。 在子組件中,不再初始化ngx-translate
,它現在集中在父組件中。 如果要在子組件之一中使用language參數,則仍可以在那里訪問當前路由,因為該參數仍是該路由的一部分,因此僅位於左側。
希望這足夠准確。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.