Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/29.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 管道将字符串更改为其JSON转换的等效值_Angular_Typescript_Pipe - Fatal编程技术网

Angular 管道将字符串更改为其JSON转换的等效值

Angular 管道将字符串更改为其JSON转换的等效值,angular,typescript,pipe,Angular,Typescript,Pipe,在我的项目中,我们必须对实体使用几个JSON翻译(JSON是按类型排序的,而不是按语言排序的)。这些实体与页面的其他国际化(我们使用ngx翻译)分离 我们已经设法通过一个获取类型的管道来参数化导入,并根据该管道获取包含转换的JSON。问题是浏览器语言只更新一次,如果语言发生更改,则不会更新此翻译 这是管道的等级 import { Pipe, PipeTransform } from '@angular/core'; import { TranslationComponent } from './

在我的项目中,我们必须对实体使用几个JSON翻译(JSON是按类型排序的,而不是按语言排序的)。这些实体与页面的其他国际化(我们使用ngx翻译)分离

我们已经设法通过一个获取类型的管道来参数化导入,并根据该管道获取包含转换的JSON。问题是浏览器语言只更新一次,如果语言发生更改,则不会更新此翻译

这是管道的等级

import { Pipe, PipeTransform } from '@angular/core';
import { TranslationComponent } from './translation.component';

@Pipe({name: 'translateType'})
export class EntityTranslatorPipe implements PipeTransform {
    constructor(private translationComponent: TranslationComponent){}

    transform(name: string, type?: string){

        return this.getNameTranslated(name, type)
    }
    async getNameTranslated(name,  type){
        const locale = this.translationComponent.userLocale+this.translationComponent.userLang
        var result
        await import('./entity/'+type+'.json').then(res =>{
            var entityJSON = JSON.parse(JSON.stringify(res));
            //We take out the entity that matches the filter(is compared removing whitespaces and in lowercase to avoid many mismatches)
            const entityFiltered = entityJSON.default.find(d => d.locale.EUen.replace(/\s+/g, '').toLowerCase() === name.replace(/\s+/g, '').toLowerCase())
            result = entityFiltered.locale[locale];
        })
        return result
    }
}
这是TranslationComponent提供的方法,负责获取浏览器的语言并由用户手动修改国际化

  public changeLanguage(lang, locale) {
    // Call translation service to use translation library
    this.translate.use(lang);

    // Sets translation variables
    this.userLang = lang;
    this.userLocale = locale;
  }
这是我们从HTML进行的管道调用

{{"carp" | translateType:"fish" | async }}
这是我们创建的第一个管道,我们发现很难得到我们想要的。 我们试图让管道变得不纯,但它不起作用,它让浏览器挂起

EDIT:我试图使管道纯粹地传递locale参数。 如何使此方法适用于所有组件

constructor(private translationComponent: TranslationComponent, private translateService: TranslateService) {}
  locale = this.translationComponent.userLocale+this.translationComponent.userLang
  aux = this.translateService.onLangChange.subscribe(lang=>{
    this.locale = this.translationComponent.getLocaleDefault(this.locale)+lang.lang;
  })
嗯,这是不纯洁的。不应该是,但确实是。返回值不仅取决于
name
,还取决于
lang
locale
,它们不是管道的参数,并且取决于非参数的值是不纯的定义

我想象,但无法检查,是杂质和导入之间的某种交互作用导致了挂起

您可以通过认识到纯响应(即仅依赖于参数
name
的响应)不是承诺,而是可观察的,在语言或区域设置发生更改时重新发出的响应,从而使其变得纯粹。考虑到这一点,您可以重新编写以下内容:

import { BehaviorSubject, pipe, merge, map, switchMap, from } from 'rxjs';

@Pipe({name: 'translateType'})
export class EntityTranslatorPipe implements PipeTransform {
  constructor(private translationComponent: TranslationComponent){}

  static readonly userLang = new BehaviorSubject('en');
  static readonly userLocale = new BehaviorSubject('en');

  transform(name: string, type?: string): Observable<string> {
    return this.getNameTranslated(name, type || '')
  }
  getNameTranslated(name: string, type: string): Observable<string> {
    return merge(EntityTranslatorPipe.userLang, 
                 EntityTranslatorPipe.this.userLocale).pipe(
      map(([lang, locale]) => async {
        const json = await import(`./entity/${lang}.json`);
        const entityFiltered = json.default.find(d => 
            d.locale.EUen.replace(/\s+/g, '').toLowerCase()
               === name.replace(/\s+/g, '').toLowerCase());
        return  entityFiltered.locale[locale];
      }),
      switchMap(from)); // flatten each Promise
  }
}
...
changeLanguage(lang, locale) {
    this.translate.use(lang);
    EntityTranslatorPipe.userLang.next(lang);
    EntityTranslatorPipe.userLocale.next(locale};
}
import{BehaviorSubject,pipe,merge,map,switchMap,from}from'rxjs';
@管道({name:'translateType'})
导出类EntityTranslatorPipe实现PipeTransform{
构造函数(私有translationComponent:translationComponent){}
静态只读userLang=new BehaviorSubject('en');
静态只读userLocale=newbehaviorsubject('en');
转换(名称:字符串,类型?:字符串):可观察{
返回此.getNameTranslated(名称,键入| |“”)
}
getNameTranslated(名称:string,类型:string):可观察{
返回合并(EntityTranslatorPipe.userLang,
EntityTranslatorPipe.this.userLocale).pipe(
映射([lang,locale])=>async{
const json=wait import(`./entity/${lang}.json`);
constEntityFiltered=json.default.find(d=>
d、 locale.EUen.replace(/\s+/g',).toLowerCase()
===name.replace(/\s+/g',).toLowerCase();
返回entityFiltered.locale[locale];
}),
switchMap(from));//展平每个承诺
}
}
...
更改语言(语言,区域设置){
这个。翻译。使用(lang);
EntityTranslatorPipe.userLang.next(lang);
EntityTranslatorPipe.userLocale.next(locale};
}

我无法在管道上实例化区域设置和更改语言的方法,因为这是由TranslationComponent完成的。如果我将区域设置添加为管道条目会怎么样?当您更改区域设置时,它将是纯的,对吗?问题是如何检测更改,因为您必须在使用管道的所有组件中执行此操作…@Yerehia-抱歉,我误读了您的原始代码。请参见编辑。
transform()
的返回值是一个可观察的值,每当
thisLang
thisleage
发出时,它都会发出。您不必检测更改:您只需使用
| async
即可,Angular将负责更新屏幕。