Javascript 角度5-在routerLink内进行ngx平移

Javascript 角度5-在routerLink内进行ngx平移,javascript,angular,routes,ngx-translate,routerlink,Javascript,Angular,Routes,Ngx Translate,Routerlink,在我的项目(Angular 5+Firebase)中,用户需要在登录页面选择语言。为此,我添加了select选项,并将所选值作为参数传递到第一页,如下所示: form_login(f:NgForm){ if (!f.valid) return; this.afAuth.auth.signInWithEmailAndPassword(f.controls.email.value, f.controls.password.value) .then(ok =&g

在我的项目(Angular 5+Firebase)中,用户需要在登录页面选择语言。为此,我添加了select选项,并将所选值作为参数传递到第一页,如下所示:

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
      });
  }
在url中有这个参数,我检索这个值并使用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);
    }
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`
    }
perfil.component.html

<h5 translate>Companyprofile</h5>
 <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
尝试在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

<h5 translate>Companyprofile</h5>
 <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

代码出了什么问题?

好的,根据我从代码中看到的内容,这里有一个建议

您的导航栏可能在某个组件中作为子组件调用,可能在
perfil.component.html
中就是这样

<navbar [parameters...]></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);
}
希望这有帮助


编辑 看到你的命令后,我知道导航栏出了什么问题。您的navbar组件是第一个被调用的组件,可以说是父组件,在子组件初始化之前构建

问题是导航栏有自己的当前路线。您试图做的是访问父组件中的子路由。我发现了一个类似的问题,并给出了一个公认的答案,但似乎不再有效。如果有必要,您可以查看它,还有另一个解决方案,尽管它看起来很棘手。所以我不确定这是不是一条路

改进建议 我看到的问题是,将语言作为子组件而不是父组件的路由参数的方法本身。当前,该语言是在导航栏的每个子路由上设置的路由参数,导致代码中大量重复。不管怎样,所有的孩子肯定都必须经历navbar初始化过程,那么为什么不在那里处理语言呢?这样,您只需在代码中的一个位置加载语言

在这种情况下,你可能需要调整你的路由器,比如这样

    { 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参数,您仍然可以在那里访问当前路由,因为该参数仍然是路由的一部分,它只是稍微靠左一点


希望这足够准确。

如果我看得没错,您正在使用
lang
变量在
navbar.component.html
中创建
routerLink
。您是否在
navbar.component.ts
文件中的某个地方设置了此变量?因为在您的代码中,我只能在
perfil.component.ts
文件中找到
lang
变量。是的,我还在
navbar.component.ts
中使用。在这种情况下,我编辑了我的问题并添加了关于
console.log
的注释。谢谢谢谢你的回答。事实上,情况恰恰相反。我重新编辑了
navbar.component.html
代码,以便您可以看到其他组件加载在navbar下面。如果您在
app.routing.module.ts
的路由代码中看到,您会注意到
PerfilComponent
NavbarComponent
的子项,后者没有路径,因此无法在路由配置中包含参数。我已使用新的解决方案更新了答案。我个人认为整个问题源于一个设计问题,应该可以很快调整。只需将
lang
参数从所有子组件切换到父组件,您就可以开始了。更新后,我尝试按照您的建议进行操作。但不幸的是,他们还没有成功。现在,第一个页面不是从
登录
页面开始,而是
导航栏
(下面没有任何内容),但URL是
http://localhost:4200/login
。此外,现在链接是使用登录作为其父路径构建的,例如
http://localhost:4200/login/agenda
。如果我理解正确,您的登录页面在正常页面之前,因此您将带有空路径的初始调用重定向到登录页面。所以第一页应该很好。从那以后,在登录本身(您选择语言的地方)之后,您必须在内部重定向(例如,在您的登录操作中的路由器调用)到导航栏链接,这当然只有在您从登录页面获得语言参数时才起作用。您的路由器中没有登录路径,您是否已经完成了选择语言的登录?是的,有两个登录路径(
{path:'',redirectTo:'/login',pathMatch:'full'}
,使登录成为每当有“/”导航时打开的页面)和登录页面(请参阅我发布的第一段代码,在这里我对用户进行身份验证并检索他们选择的语言)。