Ich habe einen Dienst SocketService erstellt, der im Grunde den Socket initialisiert, damit die App den Port abhören kann. Dieser Dienst interagiert auch mit einigen Komponenten.
// socket.service.ts
export class SocketService {
constructor() {
// Initializes the socket
}
...
}
Ich weiß, dass der Code im Konstruktor () von SocketService erst ausgeführt wird, wenn eine Komponente SocketService verwendet.
Und normalerweise sieht der Code in app.ts so aus:
// app.ts
import {SocketService} from './socket.service';
...
class App {
constructor () {}
}
bootstrap(App, [SocketService]);
Ich möchte jedoch, dass dieser Dienst ausgeführt wird, wenn die App gestartet wird. Also habe ich einen Trick gemacht, füge einfach private _socketService: SocketService
App's Konstruktor () hinzu. Jetzt sehen die Codes so aus:
// app.ts (neu)
import {SocketService} from './socket.service';
...
class App {
constructor (private _socketService: SocketService) {}
}
bootstrap(App, [SocketService]);
Jetzt funktioniert es. Das Problem ist manchmal, dass die Codes im Konstruktor () von SocketService ausgeführt werden, manchmal nicht. Wie soll ich das richtig machen? Vielen Dank
quelle
Antworten:
Die Antwort von Stuart zeigt in die richtige Richtung, aber es ist nicht einfach, Informationen zu APP_INITIALIZER zu finden. In der Kurzversion können Sie damit den Initialisierungscode ausführen, bevor einer Ihrer anderen Anwendungscodes ausgeführt wird. Ich habe eine Weile gesucht und hier und hier Erklärungen gefunden , die ich zusammenfassen werde, falls sie aus dem Internet verschwinden.
APP_INITIALIZER ist in Winkel / Kern definiert. Sie fügen es so in Ihre app.module.ts ein.
import { APP_INITIALIZER } from '@angular/core';
APP_INITIALIZER ist ein OpaqueToken (oder ein InjectionToken seit Angular 4), das auf den ApplicationInitStatus-Dienst verweist. ApplicationInitStatus ist ein Multi-Provider . Es unterstützt mehrere Abhängigkeiten und Sie können es mehrmals in Ihrer Anbieterliste verwenden. Es wird so verwendet.
@NgModule({ providers: [ DictionaryService, { provide: APP_INITIALIZER, useFactory: (ds: DictionaryService) => () => return ds.load(), deps: [DictionaryService], multi: true }] }) export class AppModule { }
Diese Providerdeklaration weist die ApplicationInitStatus-Klasse an, die DictionaryService.load () -Methode auszuführen. load () gibt ein Versprechen zurück und ApplicationInitStatus blockiert den App-Start, bis das Versprechen aufgelöst wird. Die Funktion load () ist wie folgt definiert.
load(): Promise<any> { return this.dataService.getDiscardReasons() .toPromise() .then( data => { this.dictionaries.set("DISCARD_REASONS",data); } ) }
So eingerichtet wird das Wörterbuch zuerst geladen und die anderen Teile der App können sicher davon abhängen.
Bearbeiten: Beachten Sie, dass dies die Vorladezeit für Ihre App um die Dauer der load () -Methode verlängert. Wenn Sie dies vermeiden möchten, können Sie stattdessen einen Resolver auf Ihrer Route verwenden.
quelle
init
Methode. Während Konstruktoren in der Tat so einfach wie möglich gehalten werden sollten, macht dieser Gedanke allein keine richtige Lösung. VerwendenAPP_INITIALIZER
tut.Verschieben Sie die Logik in Ihrem
SocketService
Konstruktor stattdessen in eine Methode und rufen Sie diese dann im Konstruktor Ihrer Hauptkomponente oder aufngOnInit
SocketService
export class SocketService{ init(){ // Startup logic here } }
App
import {SocketService} from './socket.service'; ... class App { constructor (private _socketService: SocketService) { _socketService.init(); } } bootstrap(App, [SocketService]);
quelle
Promise
von Ihrerinit()
Methode zurückgeben und dann nach Bedarf verketten. Was auch immer der Fall , es kann getan werden, aber wird wahrscheinlich schwierig sein , und werden Sie bis zu den Details auszuarbeiten. Wenn Sie weitere Hilfe benötigen, können Sie jederzeit eine Frage mit Details zu Ihrem genauen Problem stellen. Die Community hilft Ihnen gerne weiter.Siehe auch APP_INITIALIZER , das beschrieben wird als;
quelle
Versuchen Sie, einen Servicekonstruktor zu erstellen, und rufen Sie ihn dann in ngOnInit () Ihrer Komponente auf.
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; }); } }
Hoffe das hilft.
quelle