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

Hon*_*iao 62 typescript angular

我创建了一个服务SocketService,基本上它初始化套接字让app监听端口.此服务还与某些组件交互.

// socket.service.ts

export class SocketService {
    constructor() {
        // Initializes the socket
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

我知道SocketService的构造函数()中的代码只在组件使用SocketService时才开始运行.

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

// app.ts

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

但是,我想在应用启动时运行此服务.所以我做了一个技巧,只需添加private _socketService: SocketServiceApp的构造函数().所以现在代码看起来像这样:

// app.ts(新)

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

现在它有效.问题是有时SocketService的构造函数()中的代码运行,有时不运行.那我该怎么做呢?谢谢

GMK*_*GMK 88

斯图尔特的回答指向了正确的方向,但在APP_INITIALIZER上找到信息并不容易.简短版本是您可以在运行任何其他应用程序代码之前使用它来运行初始化代码.我搜索了一会儿,在这里这里找到了解释,如果它们从网上消失,我将总结一下.

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

import { APP_INITIALIZER } from '@angular/core';
Run Code Online (Sandbox Code Playgroud)

APP_INITIALIZER是一个引用ApplicationInitStatus服务的OpaqueToken.ApplicationInitStatus是一个多提供者.它支持多个依赖项,您可以多次在提供程序列表中使用它.它像这样使用.

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

此提供程序声明告诉ApplicationInitStatus类运行DictionaryService.load()方法.load()返回一个promise,ApplicationInitStatus阻止app启动,直到promise解析.load()函数定义如下.

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

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

编辑:请注意,无论load()方法有多长,这都会增加app的前期加载时间.如果你想避免它,你可以在路线上使用解析器.

  • 这应该是公认的答案.当前只将一行代码从构造函数移动到`init`方法.虽然构造函数确实应该尽可能简单,但仅凭这一点并不能使它成为一个合适的解决方案.使用`APP_INITIALIZER`可以. (4认同)

Sna*_*ops 50

SocketService构造函数中的逻辑移到方法中,然后在主组件的构造函数中调用它ngOnInit

SocketService

export class SocketService{
    init(){
        // Startup logic here
    }
}
Run Code Online (Sandbox Code Playgroud)

应用

import {SocketService} from './socket.service';
...
class App {
    constructor (private _socketService: SocketService) {
        _socketService.init();
    }
}
bootstrap(App, [SocketService]);
Run Code Online (Sandbox Code Playgroud)

  • 构造函数应该尽可能简单(通常只有注入点),以防需要添加额外的逻辑使用ngOnInit钩子. (8认同)

Stu*_*ows 10

另请参阅APP_INITIALIZER,其描述为;

应用程序初始化时将执行的函数。