Angular 5 Service作为单例

Sha*_*ark 5 service singleton angular

我正在研究Angular 5单例服务。我认为我按照指南做了所有事情,很遗憾,我的服务不是单例。每个组件似乎都在服务实例上。我的代码如下所示:

应用模块:

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 {
}
Run Code Online (Sandbox Code Playgroud)

服务:

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");
}
}
Run Code Online (Sandbox Code Playgroud)

星标报告组件

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;
  }
 }
Run Code Online (Sandbox Code Playgroud)

星标搜索组件

 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;
 }
 }
Run Code Online (Sandbox Code Playgroud)

现在,每次切换组件时,控制台都会显示“创建服务实例”。此外,每个组件显示错误的文本。我相信,当创建StarReportComponent时,它将切换starService.Param =“ Report”并将其保留在那里。不幸的是,当调用StarSearchComponent时,它将显示默认的“未设置”。为什么?为什么单例在这里不工作?谢谢

ama*_*mal -5

您所要求的是static您的服务中的财产。否则,它会按预期工作。如果您想自始至终为您的服务单例创建一个属性,请在您的服务中像这样声明它,

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; }

}
Run Code Online (Sandbox Code Playgroud)

编辑

哦,很抱歉,请重新阅读您的问题,它的行为符合预期。由于您this.Param = "Not Set";在服务的构造函数中,每次在组件之间切换时,它都会强制在组件中再次实例化此单例服务(通过组件中构造函数的参数),这反过来又使服务的构造函数再次被调用,从而将Param的值恢复为"Not Set"。说得通?

编辑2

回答您的评论,这是由于通过其(组件的)构造函数将服务依赖注入到组件中。

简而言之,像这样注入服务,

constructor(private starService: StarService) { }
Run Code Online (Sandbox Code Playgroud)

根据文档

提供者是可以创建或提供服务的东西。Angular 使用 来从类提供者创建服务实例new

将在幕后将private starService财产分配给,

private starService = new StarService();
Run Code Online (Sandbox Code Playgroud)

这将调用服务的构造函数。

如果您不希望每次注入服务时都发生任何默认操作,则不要在其(服务)构造函数中执行任何属性分配。

而且,每次通过其路由在组件之间切换时,都会通过调用其构造函数及其已实现的相应生命周期挂钩来创建相应的组件。因此,它还将创建在其构造函数中定义的相应依赖项。希望现在有意义。

  • 这实际上没有意义,根据此处的文档,该服务应该只创建一次,并将该实例共享给任何要求将其注入 https://angular.io/tutorial/toh-pt4 的类 (2认同)
  • 这里还有 https://angular.io/guide/dependency-injection “Angular 模块提供程序 (@NgModule.providers) 已向应用程序的根注入器注册。Angular 可以在它创建的任何类中注入相应的服务。一旦创建,服务实例随着应用程序的生命周期而存在,Angular 会在每个需要它的类中注入这个服务实例。” ---&gt; 如果您的 StarService 是实例多次,可能会出现问题 (2认同)