问题描述
我创建了一个服务SocketService,基本上它会初始化套接字以使应用程序在端口上侦听.该服务还与某些组件交互.
I created a service SocketService, basically it initializes the socket to let the app listen on the port. This service also interacts with some components.
//socket.service.ts
export class SocketService {
constructor() {
// Initializes the socket
}
...
}
我知道SocketService的Constructor()中的代码仅在组件使用SocketService时才开始运行.
I know the code in SocketService's constructor() only starts to run when a component use SocketService.
通常,app.ts中的代码如下:
And usually the code in app.ts looks like this:
//app.ts
import {SocketService} from './socket.service';
...
class App {
constructor () {}
}
bootstrap(App, [SocketService]);
但是,我希望在应用启动时运行此服务.因此,我做了一个技巧,只需在App的Constructor()中添加private _socketService: SocketService
即可.所以现在代码看起来像这样:
However, I want this service run when the app starts. So I made a trick, just add private _socketService: SocketService
in App's constructor(). So now the codes look like this:
//app.ts(新)
import {SocketService} from './socket.service';
...
class App {
constructor (private _socketService: SocketService) {}
}
bootstrap(App, [SocketService]);
现在可以使用了.问题有时是SocketService的Constructor()中的代码运行,有时却没有.那么我应该如何正确地做呢?谢谢
Now it works. The problem is sometimes the codes in SocketService's constructor() run, sometimes not. So how should I do it correctly? Thanks
推荐答案
Stuart的答案指向正确的方向,但是要查找有关APP_INITIALIZER的信息并不容易.简短的版本是您可以使用它在运行任何其他应用程序代码之前运行初始化代码.我搜索了一段时间,并在此处找到了解释和此处,进行汇总,以防它们从网络上消失.
Stuart's answer points in the right direction, but it's not easy to find information on APP_INITIALIZER. The short version is you can use it to run initialization code before any of your other application code runs. I searched for a while and found explanations here and here, which I will summarize in case they disappear from the web.
APP_INITIALIZER以角/芯定义.像这样将其包含在app.module.ts中.
APP_INITIALIZER is defined in angular/core. You include it in your app.module.ts like this.
import { APP_INITIALIZER } from '@angular/core';
APP_INITIALIZER是 OpaqueToken (或自Angular 4起的InjectionToken),它引用ApplicationInitStatus服务. ApplicationInitStatus是多提供商 .它支持多个依赖关系,您可以在提供商列表中多次使用它.这样使用.
APP_INITIALIZER is an OpaqueToken (or an InjectionToken since Angular 4) that references the ApplicationInitStatus service. ApplicationInitStatus is a multi provider. It supports multiple dependencies and you can use it in your providers list multiple times. It is used like this.
@NgModule({
providers: [
DictionaryService,
{
provide: APP_INITIALIZER,
useFactory: (ds: DictionaryService) => () => return ds.load(),
deps: [DictionaryService],
multi: true
}]
})
export class AppModule { }
此提供程序声明告诉ApplicationInitStatus类运行DictionaryService.load()方法. load()返回一个Promise,并且ApplicationInitStatus阻止应用程序启动,直到Promise解析.像这样定义了load()函数.
This provider declaration tells the ApplicationInitStatus class to run the DictionaryService.load() method. load() returns a promise and ApplicationInitStatus blocks the app startup until the promise resolves. The load() function is defined like this.
load(): Promise<any> {
return this.dataService.getDiscardReasons()
.toPromise()
.then(
data => {
this.dictionaries.set("DISCARD_REASONS",data);
}
)
}
设置为首先加载字典,然后应用程序的其他部分可以安全地依赖它.
Set up like that the dictionary gets loaded first and the other parts of the app can safely depend on it.
请注意,无论load()方法花费多长时间,这都会增加应用程序的前期加载时间.如果您想避免这种情况,可以在您的计算机上使用解析器路线.
Be aware that this will increase the up-front load time for you app by however long the load() method takes. If you want to avoid that you could use a resolver on your route instead.
这篇关于在Angular 2中启动应用程序时如何运行服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!