【问题标题】:How can I be sure a constructor function only runs once?如何确定构造函数只运行一次?
【发布时间】:2017-11-16 12:07:33
【问题描述】:

我的服务 TranslatorService 的构造函数中的这段代码有什么方法可以为所有应用程序或按需调用一次,而不是所有时间加载 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 { }

在应用模块中注入

@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>

【问题讨论】:

    标签: rxjs observable angularfire2 google-cloud-firestore


    【解决方案1】:

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

    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;
      }
    }
    

    【讨论】:

    • 在角度服务中是单例的,这不是一个好的答案,问题来自构造函数服务TranslatorService.t$ = TranslatorService.tCollection.snapshotChanges().map(actions =&gt; actions.map(a =&gt; ...)); 和我的组件ngOnInit() { this.translations$ = this.translator.translations$; } 我的组件视图中的这一行
      {{翻译 | json}}
    【解决方案2】:

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

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

    你的路由配置应该如下所示:

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

    基本上你的所有应用程序都被包装到语言组件中。

    【讨论】:

    • 这似乎是个好主意,我今天或明天试试,我回来告诉你是否一切都好,谢谢
    • 我终于改变了我的路线图并选择 ngx-translate 来管理多语言
    • 我使用的是相同的,但我仍然使用语言组件来执行特定于语言的操作。特别是在做 RTL。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-05
    • 2014-08-03
    • 1970-01-01
    • 2012-01-08
    • 2011-02-09
    相关资源
    最近更新 更多