簡體   English   中英

Angular 5-routerLink中的ngx-translate

[英]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

編輯:我所有的組件都是NavbarComponentNavbarComponent 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.componentlang變量作為輸入參數發送到導航欄。

這是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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM