Я создал службу SocketService, в основном она инициализирует сокет, чтобы приложение могло прослушивать порт. Этот сервис также взаимодействует с некоторыми компонентами.
// socket.service.ts
export class SocketService {
constructor() {
// Initializes the socket
}
...
}
Я знаю, что код в SocketService constructor () запускается только тогда, когда компонент использует SocketService.
И обычно код в app.ts выглядит так:
// app.ts
import {SocketService} from './socket.service';
...
class App {
constructor () {}
}
bootstrap(App, [SocketService]);
Однако я хочу, чтобы эта служба запускалась при запуске приложения. Итак, я сделал хитрость, просто добавил private _socketService: SocketService
конструктор приложения (). Итак, теперь коды выглядят так:
// app.ts (новое)
import {SocketService} from './socket.service';
...
class App {
constructor (private _socketService: SocketService) {}
}
bootstrap(App, [SocketService]);
Теперь это работает. Проблема в том, что иногда коды в SocketService constructor () выполняются, а иногда нет. Так как мне это сделать правильно? Благодарность
typescript
angular
Хунбо Мяо
источник
источник
Ответы:
Ответ Стюарта указывает в правильном направлении, но найти информацию о APP_INITIALIZER непросто. Краткая версия заключается в том, что вы можете использовать его для запуска кода инициализации перед запуском любого другого кода вашего приложения. Некоторое время я искал и нашел объяснения здесь и здесь , которые я кратко изложу на случай, если они исчезнут из Интернета.
APP_INITIALIZER определяется в angular / core. Вы включаете его в свой 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) => () => 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 (). Если вы хотите избежать этого, вы можете вместо этого использовать преобразователь на своем маршруте.
источник
init
метод. Хотя конструкторы действительно должны быть как можно более простыми, сама по себе эта мысль не делает ее правильным решением. ИспользованиеAPP_INITIALIZER
делает.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]);
источник
Promise
из своегоinit()
метода, а затем связать по мере необходимости. В любом случае это можно сделать, но, вероятно, это будет сложно, и вам придется проработать детали. Если вам нужна дополнительная помощь, вы всегда можете задать вопрос с подробным описанием вашей проблемы, и сообщество с радостью вам поможет.Также см. APP_INITIALIZER , который описывается как;
источник
Попробуйте создать конструктор службы, а затем вызовите его в ngOnInit () вашего компонента.
export class SocketService { constructor() { } getData() { //your code Logic } }
export class AppComponent { public record; constructor(private SocketService: DataService){ } ngOnInit() { this.SocketService.getData() .subscribe((data:any[]) => { this.record = data; }); } }
Надеюсь это поможет.
источник