Javascript Angular2等待JSON文件加载

Javascript Angular2等待JSON文件加载,javascript,json,typescript,angular,Javascript,Json,Typescript,Angular,目前,我正在加载一个JSON文件,如下所示: 翻译服务 可本地化的.it.strings MyTranslationService被注入MyHomeComponent中,但问题是当我尝试通过管道读取这些值时,在呈现页面时仍需要加载这些值 翻译.pipe.ts 知道如何在加载任何页面之前加载JSON文件中的所有值吗?我认为您不应该尝试使代码同步。相反,让TranslationService告诉您何时准备就绪: export class TranslationService { // ...

目前,我正在加载一个JSON文件,如下所示:

翻译服务

可本地化的.it.strings

My
TranslationService
被注入My
HomeComponent
中,但问题是当我尝试通过管道读取这些值时,在呈现页面时仍需要加载这些值

翻译.pipe.ts


知道如何在加载任何页面之前加载JSON文件中的所有值吗?

我认为您不应该尝试使代码同步。相反,让
TranslationService
告诉您何时准备就绪:

export class TranslationService {
    // ...

    get isReady() {
        return !!this._messages;
    }
}
只有当
\u messages
不为空时,管道才能返回翻译

export class TranslatePipe implements PipeTransform {
    // ...

    transform(value: string, args: string[]) : any {
        return this._translation.isReady
            ? this._translation.getTranslationByKey(value) : null;
    }
}

我认为您可以稍微调整一下您的服务和管道,以便在数据准备就绪/加载到后台时进行处理

首先添加一个observable,以便在数据加载到您的服务中时通知:

@Injectable()
export class TranslationService {

  private _messages = {};

  private translationLoaded : Observable<boolean>;
  private translationLoadedObserver : Observer<boolean>;

  constructor(private _http: Http) {
    this.translationLoaded = Observable.create((observer) => {
      this.translationLoadedObserver = observer;
    });

    var observable = this._http.get("app/i18n/localizable.it.strings").map((res: Response) => res.json());
    observable.subscribe(res => {
      this._messages = res;
      this.translationLoadedObserver.next(true);
    });
  }

  getTranslationByKey(key: string, args?: any[]) {
    return this._messages[key];
  }
}

这是对应的plunkr:。

在这种情况下,在我加载的第一个页面上,它将始终返回null。否,只有在加载JSON之前,它才会为空,然后Angular将使用此管道自动更新所有表达式。最后,您可以使用
包装整个内容,在翻译准备就绪后将显示此内容。
export class TranslationService {
    // ...

    get isReady() {
        return !!this._messages;
    }
}
export class TranslatePipe implements PipeTransform {
    // ...

    transform(value: string, args: string[]) : any {
        return this._translation.isReady
            ? this._translation.getTranslationByKey(value) : null;
    }
}
@Injectable()
export class TranslationService {

  private _messages = {};

  private translationLoaded : Observable<boolean>;
  private translationLoadedObserver : Observer<boolean>;

  constructor(private _http: Http) {
    this.translationLoaded = Observable.create((observer) => {
      this.translationLoadedObserver = observer;
    });

    var observable = this._http.get("app/i18n/localizable.it.strings").map((res: Response) => res.json());
    observable.subscribe(res => {
      this._messages = res;
      this.translationLoadedObserver.next(true);
    });
  }

  getTranslationByKey(key: string, args?: any[]) {
    return this._messages[key];
  }
}
@Pipe({
  name: 'translate',
  pure: false  // required to update the value when data are loaded
})
export class TranslatePipe implements PipeTransform {
  constructor(private _ref :ChangeDetectorRef, private _translation: TranslationService) {
    this.loaded = false;
  }

  transform(value: string, args: string[]) : any {
    this.translationLoadedSub = this._translation.translationLoaded.subscribe((data) => {
      this.value = this._translation.getTranslationByKey(value);
      this._ref.markForCheck();
      this.loaded = true;
    });

    if (this.value == null && this.loaded) {
      this.value = this._translation.getTranslationByKey(value);
    }
    return this.value;
  }

  _dispose(): void {
    if(isPresent(this.translationLoadedSub)) {
      this.translationLoadedSub.unsubscribe();
      this.translationLoadedSub = undefined;
    }
  }

  ngOnDestroy(): void {
    this._dispose();
  }
}