【问题标题】:translate.get sometimes returns key instead of translationtranslate.get 有时会返回键而不是翻译
【发布时间】:2021-11-04 05:00:24
【问题描述】:

我目前正在开发一个基于 Angular 12 的 Web 应用程序,该应用程序使用 ngx-translate 进行国际化,使用 ASP.NET Core 5 作为后端。在向项目添加新页面的组件(包括路由和所有内容)后,它拒绝翻译我希望它在新组件中翻译的任何内容,而是显示翻译键。在清除浏览器缓存,删除项目的所有临时文件并完全重新编译所有内容后,它现在似乎工作正常。但是,仍然有一些奇怪的事情发生,我无法解释。 当我将以下行添加到我的新组件的 ngOnInit() 方法时,它有时可以正常工作,但有时只返回翻译键而不是翻译:

console.log("TEST: ", this.translate.instant('login.success'));

查看文档后发现,instant() 方法只能在确保已加载翻译后使用。或者,文档提到可以使用 get() 方法来避免此问题。我试过了,但有时它仍然返回翻译键而不是翻译。这怎么可能?我该如何解决这个问题?

app.module.ts 导入:

export function HttpLoaderFactory(http: HttpClient) {
  return new TranslateHttpLoader(http, './assets/i18n/', '.json');
}
...
TranslateModule.forRoot({
      loader: {
        provide: TranslateLoader,
        useFactory: HttpLoaderFactory,
        deps: [HttpClient]
      }
    })

app.component 构造函数:

constructor(private spinner: NgxSpinnerService, public translate: TranslateService) {
  translate.addLangs(['en', 'de']);
  translate.setDefaultLang('en');

  const browserLang = translate.getBrowserLang();
  translate.use(browserLang.match(/en|de/) ? browserLang : 'en');
}

app-routing.module:

const routes: Routes = [
  {
    path: "",
    redirectTo: "/login",
    pathMatch: 'full'
  },
  {
    path: "login",
    component: LoginComponent
  },
  {
    path: "landing",
    component: LandingComponent,
    children: [
      {
        path: "",
        component: LandingContentComponent,
      },
      {
        path: "new-component",
        loadChildren: () =>
          import("./new-component/new-component.module").then(
            (m) => m.NewComponentModule
          ),
      },
      { path: "**", redirectTo: "landing" },
    ]
  },
  { path: "**", component: NotFoundComponent },
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

新的组件模块:

...
export function HttpLoaderFactory(http: HttpClient) {
  return new TranslateHttpLoader(
    http
  );
}


@NgModule({
  declarations: [
    NewComponentComponent
  ],
  imports: [
    ...

    TranslateModule.forChild({
      loader: {
        provide: TranslateLoader,
        useFactory: (HttpLoaderFactory),
        deps: [HttpClient]
      },
      extend: true
    })
  ],
})
export class NewComponentModule { }

新的component.component.ts:

import { Component, OnInit } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';

@Component({
  selector: 'app-new-component',
  templateUrl: './new-component.component.html',
  styleUrls: ['./new-component.component.scss']
})
export class NewComponentComponent implements OnInit {

  constructor(public translate: TranslateService) { }

  ngOnInit(): void {
    this.translate.get('login.success').subscribe((translated: string) => {
      console.log("TEST: ", translated);
    });
  }
}

【问题讨论】:

    标签: angular visual-studio asp.net-core ngx-translate


    【解决方案1】:

    发生这种情况是因为您 extend root 翻译在延迟加载模块中,并使用 TranslateHttpLoader 延迟加载其翻译。

    由于TranslateHttpLoader正在加载翻译async,所以它可能会在初始化组件之前完成加载(因此在这种情况下您可以正确获取翻译)或可能不会,这导致this.translate.get函数获取来自root 键的翻译并在失败时返回键本身。

    因此,要解决此问题,您必须确保延迟加载的翻译已正确加载,然后再尝试get/instant 任何键的翻译,感谢Angular Resolver,可以在类似情况下使用:

    路由器在路由最终激活之前等待数据解析。

    所以我们可以创建自己的resolver,以确保在解决(完成)resolverobservable 之前,不会初始化组件(因为不会激活路由)。

    另一方面,感谢 ngx-translate getTranslation 函数,它返回一个 observable,它发出一个使用当前加载器加载的翻译对象:

    获取给定语言的翻译对象与当前 loader 并通过编译器传递它

    所以resolver 将如下所示:

    @Injectable({ providedIn: 'root' })
    export class TranslationResolverService implements Resolve<any> {
      constructor(private translateService: TranslateService) {}
    
      resolve(): Observable<any> {
        return this.translateService.getTranslation(
          this.translateService.currentLang
        );
      }
    }
    

    您可以将其包含在resolve 下的NewComponentModule 路由中,如下所示:

    const routes: Routes = [
      {
        path: '',
        resolve: [TranslationResolverService],
        component: NewComponentComponent,
        children: [
          // .....
        ],
      },
    ];
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-01-29
      • 1970-01-01
      • 2020-03-07
      • 1970-01-01
      • 1970-01-01
      • 2016-02-05
      • 2018-03-08
      相关资源
      最近更新 更多