2017-12-22 21 views
2

Ich arbeite an Angular 5 Singleton Service. Meiner Meinung nach habe ich alles nach Leitlinie gemacht, leider ist mein Service kein Singleton. Jede Komponente scheint sich auf der Dienstinstanz zu befinden. Mein Code sieht wie folgt aus:Angular 5 Service Als Singleton

App Modul:

import { StarService } from './star-service/star-service' 
import { StarSearchComponent } from './star-search/star-search.component' 
import { StarReportComponent } from './star-report/star-report.component'; 
@NgModule({ 
imports: [ 
BrowserModule, 
    FormsModule, 
    AppRoutingModule 
], 
declarations: [ 
AppComponent, 
StarSearchComponent, 
StarReportComponent 
], 
providers: [StarService 
], 
bootstrap: [AppComponent] 
}) 
export class AppModule { 
} 

Service:

import { Injectable } from '@angular/core'; 
import { log } from 'util'; 
@Injectable() 
export class StarService { 
public Param: string; 

constructor() { 
this.Param = "Not Set"; 
console.log("Service Instance created"); 
} 
} 

Stern-Bericht Component

import { Component, OnInit } from '@angular/core'; 
import { StarService } from '../star-service/star-service' 
@Component({ 
    selector: 'app-star-report', 
    templateUrl: '<p>{{getReport}}</p>', 
    styleUrls: ['./star-report.component.css'] 
}) 
export class StarReportComponent implements OnInit { 

    constructor(private starService: StarService) { } 
    ngOnInit() { 
    this.starService.Param = "Report"; 
} 

get getReport(): string 
    { 
    return this.starService.Param; 
    } 
} 

Star Search Component

import { Component, OnInit } from '@angular/core'; 
import { StarService } from '../star-service/star-service' 

@Component({ 
selector: 'app-star-search', 
templateUrl: './star-search.component.html', 
styleUrls: ['./star-search.component.css'] 
}) 
export class StarSearchComponent implements OnInit { 
    constructor(private starService: StarService) { } 
ngOnInit() { 
    } 
get getSearch(): string 
{ 
    return this.starService.Param; 
} 
} 

Und nun, meine Konsole zeigt "Service-Instanz erstellt" jedes Mal, wenn ich bin Schaltkomponente. Außerdem zeigt jede Komponente falschen Text an. Ich glaube, wenn StarReportComponent erstellt wird, wechselt es starService.Param = "Report" und es soll dort bleiben. Leider, wenn StarSearchComponent aufgerufen wird, zeigt es standardmäßig "Nicht festgelegt" an. Warum? Warum Singleton hier nicht funktioniert? Danke

+0

Ich kann dies nicht mit Ihrem Beispielcode reproduzieren: https://stackblitz.com/edit/angular-mwxab5?file=app%2Fapp.component.ts –

+0

Danke, ich sehe, dass Sie beide Komponenten in der gleichen erstellen Zeit: . Ich wechsle eher zwischen ihnen durch das Routing. Macht es einen Unterschied? – Shark

Antwort

-1

Was Sie verlangen, ist ein static Eigentum in Ihrem Service. Ansonsten funktioniert es wie erwartet. Wenn Sie eine Eigenschaft Ihres Service Singleton machen wollen im gesamten, erklären es so in Ihren Dienst,

export class StarService { 

static _param: string; 

// use getters and setters to access them from your instantiated service objects from within various components 
get Param() { return StarService._param; } 

set Param(param: string) { StarService._param = param; } 

} 

EDIT

Oh Es tut mir leid, gerade wieder lesen Ihre Frage, es verhält wie erwartet. Da Sie im Konstruktor Ihres Dienstes this.Param = "Not Set"; haben, zwingt es jedes Mal, wenn Sie zwischen Ihren Komponenten wechseln, die Instanziierung dieses Singleton-Dienstes in Ihrer Komponente (über das Argument des Konstruktors in Ihrer Komponente), was wiederum den Konstruktor des Dienstes erneut aufruft Somit wird der Wert Param auf "Not Set" zurückgesetzt. Macht Sinn?

EDIT-2

Ihren Kommentar zu beantworten, ist es aufgrund der dependency injection des Dienstes in das Bauteil durch seine (Komponente) Konstruktor getan.

Kurz gesagt, den Dienst wie diese Injektion,

constructor(private starService: StarService) { } 

gemäß der docs,

Ein Anbieter ist etwas, das einen Dienst erstellen oder liefern. Angular erstellt eine Serviceinstanz von einem Klassenanbieter mithilfe von new.

unter der Haube wird die private starService Eigenschaft auf,

private starService = new StarService(); 

zuweisen, die den Dienst des Konstruktor rufen.

Wenn Sie nicht möchten, dass jedes Mal, wenn der Service injiziert wird, Standardaktionen ausgeführt werden, führen Sie keine Eigenschaftszuweisungen innerhalb des (Service-) Konstruktors aus.

Und jedes Mal, wenn Sie zwischen Komponenten durch seine Routen wechseln, wird die entsprechende Komponente durch Aufruf seines Konstruktors erstellt und die entsprechende lifecycle hooks implementiert. Daher werden auch die entsprechenden Abhängigkeiten erstellt, die in ihren Konstruktoren definiert sind. Hoffe es macht jetzt Sinn.

+0

Ich weiß, wie statische funktioniert, aber ich frage, warum StarService nicht als Singleton injiziert wird? – Shark

+0

aktualisiert meine Antwort, bitte überprüfen Sie es – amal

+0

Danke. Aber warum Service Constructor wird mehrmals aufgerufen? Singleton wird nur einmal erstellt, oder? – Shark

0

Ich hatte schon lange mit diesem Problem zu kämpfen. Ich wollte ein Singleton haben und wann immer ich von einem Link zum anderen geroutet wurde, wurde der Dienst, von dem ich erwartete Singleton zu sein, neu erstellt. Schließlich war die Lösung, um die Navigationslink zu ändern:

Von:

<a href="/customers">Customers</a>

An:

<a routerLink="/customers">Customers</a>

ich den Link von Winkel Dokumentation über Singletons die Verwendung entfernen gegabelt haben von commonModule und sharedmodule um zu beweisen, dass dies nicht das Problem verursacht. Obwohl ich stimme zu, dass die Verwendung von commonModule und sharedModule die Module modularer macht.

https://stackblitz.com/edit/angular-uxbbdx

Ich habe faul Laden von Modulen ähnlich dem Beispiel. Lassen Sie mich wissen, ob dies das Problem für Sie löst. Ich habe schon eine ganze Weile mit diesem Problem herumgespielt und werde wahrscheinlich helfen können, das Problem erneut zu erstellen.