Angular 5 Service As singleton

问题描述 投票:4回答:2

我正在研究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 {
}

服务:

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

星报表组件

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

星搜索组件

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

现在,每次切换组件时,我的控制台都会显示“Service Instance created”。此外,每个组件显示错误的文本。我相信,当StarReportComponent创建时,它会切换starService.Param =“Report”,它将保留在那里。不幸的是,当调用StarSearchComponent时,它会显示默认的“Not Set”。为什么?为什么单身人士不在这里工作?谢谢

angular service singleton
2个回答
-3
投票

您要求的是您服务中的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; }

}

编辑

哦,对不起,只是重新阅读你的问题,它表现得像预期的那样。由于在服务的构造函数中有this.Param = "Not Set";,每次在组件之间切换时,它会强制在组件中再次实例化此单例服务(通过组件中的构造函数的参数),这反过来又会使服务的构造函数再次调用,因此将Param的价值恢复为"Not Set"。说得通?

编辑-2

回答你的评论,这是由于服务的dependency injection通过其(组件)构造函数完成的。

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

constructor(private starService: StarService) { }

根据docs

提供者可以创建或提供服务。 Angular使用new从类提供程序创建服务实例。

将在引擎盖下分配private starService财产,

private starService = new StarService();

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

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

并且,每次通过其路径在组件之间切换时,通过调用其构造函数和它已实现的相应lifecycle hooks来创建相应的组件。因此,它也将创建在其构造函数中定义的相应依赖项。希望现在有意义。


3
投票

很长一段时间我一直在努力解决这个问题。我想要一个单身人士,每当我从一个链接路由到另一个链接时,我希望它是单身的服务被重新创建。最后解决方案是更改导航链接:

来自:

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

至:

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

我已经从单例上的角度文档分离链接,以删除commonmodule和sharedmodule的用法,以证明这不会导致问题。虽然我同意使用commonmodule和sharedmodule使模块更加模块化。

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

我有类似于示例的延迟加载模块。如果这不能解决您的问题,请告诉我。我已经玩了很长一段时间来解决这个问题,并且可能会通过再次重现这个问题来提供帮助。

© www.soinside.com 2019 - 2024. All rights reserved.