如何确保构造函数只运行一次?

时间:2017-11-16 12:07:33

标签: rxjs observable angularfire2 google-cloud-firestore

在我的服务的构造函数中是否有任何方法可以使用TranslatorService为所有应用程序或demande调用一次,而不是所有时间homecomponent都加载????

this.translations$ = translationsCollection.snapshotChanges().map(actions => {
      return actions.map(a => {
        ...
      })

我的翻译翻译课程来自firestore ex:

{
  "WELCOME": {
   "FR": "bienvenue",
   "GB": "Welcome"
 }
}

export interface Translation {
    [code: string]: TranslationInfo;

}

export interface TranslationInfo {
    [language: string]: string;
}

我的核心模块

import { NgModule } from '@angular/core';
import { AuthService } from './auth.service';
import { AngularFireAuthModule } from 'angularfire2/auth';
import { AngularFirestoreModule } from 'angularfire2/firestore';
import { TranslatorService } from '../services/translator.service';
@NgModule({
imports: [
    AngularFireAuthModule,
    AngularFirestoreModule
],
providers: [AuthService, TranslatorService]
})
export class CoreModule { }

在appmodule中注入

@NgModule({
declarations: [
...

],
imports: [
...
    CoreModule,
...
],
providers: [AuthGuard],
bootstrap: [AppComponent]
})
export class AppModule { }

我的翻译服务

    @Injectable()
export class TranslatorService {

  translationsCollection: AngularFirestoreCollection<Translation>;
  translations$: Observable<any>;
  public translations: Translation[];

  constructor(private afs: AngularFirestore) {
    var translationsCollection = this.afs.collection("translations");
    this.translations$ = translationsCollection.snapshotChanges().map(actions => {
      return actions.map(a => {
        ...
      })
    });

我的组件

    export class HomeComponent implements OnInit {
translations$: Observable<any>;
constructor(private translator: TranslatorService) { }

ngOnInit() {
    this.translations$ = this.translator.translations$;
}

我的组件视图

<div *ngFor="let translation of translations$|async">
<pre>{{translation | json}}</pre>
</div>

2 个答案:

答案 0 :(得分:2)

只需使用单例模式:将代码移动到静态函数并将其结果存储在静态字段中。构造函数只调用静态函数,它将在运行代码之前检查字段:

export class TranslatorService {

  translationsCollection: AngularFirestoreCollection<Translation>;
  translations$: Observable<any>;

  static tCollection : AngularFirestoreCollection<Translation>;
  static t$: Observable<any>;
  static initialize(afs: AngularFireStore) : void {
    if (TranslatorService.tCollection == null) {
      TranslatorService.tCollection = afs.collection("translations");
      TranslatorService.t$ = TranslatorService.tCollection.snapshotChanges().map(actions => actions.map(a => ...));
    }
  }

  public translations: Translation[];

  constructor(private afs: AngularFirestore) {
    TranslatorService.initialize(this.afs);
    this.translations$ = TranslatorService.t$;
    this.translationsCollection = TranslatorService.tCollection;
  }
}

答案 1 :(得分:0)

我在其中一个项目中做过类似的事情。您只需将翻译代码移到上一级即可。即

创建一个名为translation组件的组件,它包装所有组件并将逻辑放入其中。这样,它只会在应用程序生命周期中加载一次。

您的路由配置应该看起来如下:

const routes: Routes = [
    {
        path: '', component: LanguageComponent,
        children: [
            { path: '', component: HomeComponent },
            { path: 'login', component: LoginComponent },
        ]
    }
];

基本上所有应用程序都包含在语言组件中。