当应用程序在 Angular 2 中启动时如何运行服务

新手上路,请多包涵

我创建了一个服务SocketService,基本上它初始化套接字让应用程序监听端口。该服务还与一些组件交互。

// socket.service.ts

 export class SocketService {
    constructor() {
        // Initializes the socket
    }
    ...
}

我知道 SocketService 的 constructor() 中的代码只有在组件使用 SocketService 时才开始运行。

通常 app.ts 中的代码如下所示:

// 应用程序.ts

 import {SocketService} from './socket.service';
...
class App {
    constructor () {}
}
bootstrap(App, [SocketService]);

但是,我希望在应用程序启动时运行此服务。所以我做了一个技巧,在App的constructor()中添加 private _socketService: SocketService 。所以现在代码看起来像这样:

// app.ts(新)

 import {SocketService} from './socket.service';
...
class App {
    constructor (private _socketService: SocketService) {}
}
bootstrap(App, [SocketService]);

现在它起作用了。问题有时是 SocketService 的 constructor() 中的代码运行,有时不是。那么我应该如何正确地做到这一点呢?谢谢

原文由 Hongbo Miao 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 545
2 个回答

Stuart 的回答指向了正确的方向,但在 APP_INITIALIZER 上查找信息并不容易。简短的版本是您可以在任何其他应用程序代码运行之前使用它来运行初始化代码。我搜索了一段时间,在 这里这里 找到了解释,我会总结一下,以防它们从网络上消失。

APP_INITIALIZER 在 angular/core 中定义。你像这样将它包含在你的 app.module.ts 中。

 import { APP_INITIALIZER } from '@angular/core';

APP_INITIALIZER 是一个引用 ApplicationInitStatus 服务的 OpaqueToken (或从 Angular 4 开始的 InjectionToken)。 ApplicationInitStatus 是一个 多提供者。它支持多个依赖项,您可以在提供程序列表中多次使用它。它是这样使用的。

 @NgModule({
  providers: [
    DictionaryService,
    {
      provide: APP_INITIALIZER,
      useFactory: (ds: DictionaryService) => () => return ds.load(),
      deps: [DictionaryService],
      multi: true
    }]
})
export class AppModule { }

此提供程序声明告诉 ApplicationInitStatus 类运行 DictionaryService.load() 方法。 load() 返回一个承诺,ApplicationInitStatus 会阻止应用程序启动,直到承诺解决。 load() 函数是这样定义的。

 load(): Promise<any> {
  return this.dataService.getDiscardReasons()
  .toPromise()
  .then(
    data => {
      this.dictionaries.set("DISCARD_REASONS",data);
    }
  )
}

设置为首先加载字典,应用程序的其他部分可以安全地依赖它。

编辑:请注意,无论 load() 方法花费多长时间,这都会增加您应用程序的前期加载时间。如果您想避免这种情况,您可以在您的路线上使用 解析器

原文由 GMK 发布,翻译遵循 CC BY-SA 4.0 许可协议

套接字服务.ts

 import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root',
})
export class SocketService {
  init() {
    console.log("socket service initialized");
  }
}

app.component.ts

 import { Component } from '@angular/core';
import {SocketService} from './socket.service';

@Component({
  selector: 'app-root',
  templateUrl: 'app.component.html',
  styleUrls: ['app.component.scss'],
})
export class AppComponent {
  constructor(private _socketService: SocketService) {
    this._startupService.init();
  }
}

原文由 Mo D Genesis 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进