Ionic ngx-翻译-多-http-加载器:以下翻译文件出错

yzckvree  于 2022-12-16  发布在  Ionic
关注(0)|答案(1)|浏览(132)

我正在使用这个库ngx-translate-multi-http-loader,以便能够为我的离子5应用程序加载多语言文件。
我没有任何错误,但翻译不起作用。
然后,我在TranslateModule.forRoot({})中添加了defaultLanguage: 'en',然后产生了以下错误消息
以下翻译文件出错:./assets/i18n/en.json
未创建数据库。必须首先调用create()
我需要很多时间来弄清楚如何修复它,在互联网上找不到任何帮助。

dced5bon

dced5bon1#

2023修复

在〉= 9.2.0的情况下,这个错误不会再发生。因为库现在使用httpBackend

错误

This topic为我指出了正确的方向。基本上,我们用来导入翻译文件的所需加载程序

export function HttpLoaderFactory(httpClient: HttpClient) {
  return new MultiTranslateHttpLoader(httpClient, [
    { prefix: './assets/i18n/', suffix: '.json' },
    { prefix: `./assets/i18n/${APP_CONFIG.appType}/`, suffix: '.json' },
  ])
}

直接导入到app.module中.ts @ngModule

TranslateModule.forRoot({
  loader: {
    provide: TranslateLoader,
    useFactory: HttpLoaderFactory,
    deps: [HttpClient],
  },
}),

如果你发现这篇文章,这肯定意味着你在你的应用程序中使用了HttpInterceptor,它确实从离子存储(或任何其他服务)请求数据,以将特定逻辑应用于请求-〉比方说,你想向请求添加一个令牌。
让我们看下面这个例子

@Injectable()
export class AuthHttpInterceptor implements HttpInterceptor {
  constructor(private _storage: Storage) {}

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<any> {

    // Clone the request to add the new header.
    let authReq: any
    return from(this.getToken()).pipe(
      switchMap((token) => {
        if (!req.headers.get('Authorization'))
          authReq = req.clone({
            headers: req.headers.set('Authorization', `Bearer ${token}`),
          })
        else authReq = req.clone()

        //send the newly created request
        return next.handle(authReq).pipe(
          retry(1),
          catchError((err, caught) => {

            const error = (err && err.error && err.error.message) || err.statusText
            return throwError(error)
          }) as any,
        )
      }),
    )
  }

  getToken(): Observable<any> {
    const token$ = new Observable((observer) => {
      this._storage.get('token').then(async (token) => {
        if (token) {
          observer.next(token)
        } else {
          observer.next(ORGANISATION_TOKEN)
        }
      })
    })

    return token$
  }
}

然后,由于ngx-translate-multi-http-loader正在请求带有Angular 默认http类的翻译文件,您将通过此http拦截器。但是_storage尚未示例化。这将导致Database not created. Must call create() first,使我们的请求无法进入Something went wrong for the following translation file: ./assets/i18n/en.json

修复

对于那个特定的请求,我们必须忽略这个拦截器。
为此目的:
1.你可以用httpBackend-〉here an explanation来实现,但是它不起作用,因为你在调用http之前没有示例化你的服务。
1.你必须添加一个特定的头,告诉你的HttpInterceptor忽略请求,让它通过没有进一步的调查. *Thx JohnrSharpe *

export const InterceptorSkipHeader = 'X-Skip-Interceptor'

@Injectable()
export class UsHttpInterceptor implements HttpInterceptor {
  constructor(private _storage: Storage, private _statusService: MegaphoneStatusService) {}

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<any> {
    if (req.headers.has(InterceptorSkipHeader)) {
      const headers = req.headers.delete(InterceptorSkipHeader)
      return next.handle(req.clone({ headers }))
    }

   //... Intercept

为了能够将该头文件传递到ngx-translate-multi-http-loader中,嗯...你不能。因为库不接受它,但复制它并不复杂。

// core.ngx-loader.ts

import { HttpClient, HttpHeaders } from '@angular/common/http'
import { TranslateLoader } from '@ngx-translate/core'
import merge from 'deepmerge'
import { forkJoin, Observable, of } from 'rxjs'
import { catchError, map } from 'rxjs/operators'
import { InterceptorSkipHeader } from '../http.interceptor'

export class MultiTranslateHttpLoader implements TranslateLoader {
  constructor(
    private http: HttpClient,
    private resources: {
      prefix: string
      suffix: string
    }[],
  ) {}

  public getTranslation(lang: string): Observable<any> {
    const headers = new HttpHeaders().set(InterceptorSkipHeader, '') // <-- Our Skip interceptor

    const requests = this.resources.map((resource) => {
      const path = resource.prefix + lang + resource.suffix

      return this.http.get(path, { headers }).pipe( // <-- We add the header into the request
        catchError((res) => {
          console.error('Something went wrong for the following translation file:', path)
          console.error(res.message)
          return of({})
        }),
      )
    })

    return forkJoin(requests).pipe(map((response) => merge.all(response)))
  }
}

你就在这儿。

相关问题