Как запустить службу, когда приложение запускается в Angular 2
Я создал службу SocketService, в основном она инициализирует сокет, чтобы приложение прослушивало порт. Эта служба также взаимодействует с некоторыми компонентами.
//socket.service.ts
export class SocketService {
constructor() {
// Initializes the socket
}
...
}
Я знаю, что код в конструкторе SocketService() запускается только тогда, когда компонент использует SocketService.
И обычно код в app.ts выглядит так:
//app.ts
import {SocketService} from './socket.service';
...
class App {
constructor () {}
}
bootstrap(App, [SocketService]);
Тем не менее, я хочу, чтобы эта служба запускалась при запуске приложения. Поэтому я сделал трюк, просто добавьте private _socketService: SocketService
в конструктор App(). Итак, теперь коды выглядят так:
//app.ts(новый)
import {SocketService} from './socket.service';
...
class App {
constructor (private _socketService: SocketService) {}
}
bootstrap(App, [SocketService]);
Теперь он работает. Иногда иногда возникают ошибки в конструкторе SocketService(), иногда нет. Итак, как мне это сделать правильно? Благодаря
Ответы
Ответ 1
Переместите логику в конструкторе SocketService
вместо метода, а затем вызовите это в своем конструкторе основного компонента или ngOnInit
SocketService
export class SocketService{
init(){
// Startup logic here
}
}
приложения
import {SocketService} from './socket.service';
...
class App {
constructor (private _socketService: SocketService) {
_socketService.init();
}
}
bootstrap(App, [SocketService]);
Ответ 2
Ответ стюарта указывает в правильном направлении, но найти информацию на APP_INITIALIZER непросто. Короткая версия - вы можете использовать ее для запуска кода инициализации до запуска любого другого кода вашего приложения. Я некоторое время искал и нашел объяснения здесь и здесь, которые я обобщу на случай, если они исчезнут из Интернета.
APP_INITIALIZER определяется в angular/основных. Вы включаете его в свой app.module.ts вот так.
import { APP_INITIALIZER } from '@angular/core';
APP_INITIALIZER - это OpaqueToken (или InjectionToken начиная с Angular 4), который ссылается на службу ApplicationInitStatus. ApplicationInitStatus является мульти-провайдером. Он поддерживает несколько зависимостей, и вы можете использовать его в своем списке поставщиков несколько раз. Используется так.
@NgModule({
providers: [
DictionaryService,
{
provide: APP_INITIALIZER,
useFactory: (ds: DictionaryService) => function() {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(). Если вы хотите избежать этого, вы можете вместо этого использовать resolver на своем маршруте.
Ответ 3
Также см. APP_INITIALIZER, который описывается как
Функция, которая будет выполняться при инициализации приложения.
Ответ 4
Попробуйте создать конструктор службы, а затем вызовите его в ngOnInit() вашего компонента.
export class SocketService {
constructor() { }
getData() {
//your code Logic
}
}