简体   繁体   English

Angular 5 Service As singleton

[英]Angular 5 Service As singleton

I'm working on Angular 5 singleton service. 我正在研究Angular 5单件服务。 In my opinion I did everything according to guideline, unfortunately my service is NOT singleton. 在我看来,我按照指南做了一切,不幸的是我的服务不是单身。 Each component seems to have it's on service instance. 每个组件似乎都在服务实例上。 My Code looks like this: 我的代码看起来像这样:

App Module: 应用模块:

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

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

And now, my console displays "Service Instance created" each time I'm switching component. 现在,每次切换组件时,我的控制台都会显示“Service Instance created”。 Also, each component display wrong text. 此外,每个组件显示错误的文本。 I belive, when StarReportComponent is create, it switches starService.Param = "Report" and it shall stay there. 我相信,当StarReportComponent创建时,它会切换starService.Param =“Report”,它将保留在那里。 Unfortunatelly, when StarSearchComponent is called, it displays default "Not Set". 不幸的是,当调用StarSearchComponent时,它会显示默认的“Not Set”。 Why? 为什么? Why singleton is not working here? 为什么单身人士不在这里工作? Thanks 谢谢

I was struggling with this problem for quite some time. 很长一段时间我一直在努力解决这个问题。 I wanted to have a singleton and whenever I routed from one link to the other the service, that I expected to be singleton, was recreated. 我想要一个单身人士,每当我从一个链接路由到另一个链接时,我希望它是单身的服务被重新创建。 Finally the solution was to change the navigation link: 最后解决方案是更改导航链接:

From : 来自:

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

To: 至:

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

I have forked the link from angular documentation on singleton to remove the usage of commonmodule and sharedmodule to prove that this isn't causing the problem. 我已经从单例上的角度文档分离链接,以删除commonmodule和sharedmodule的用法,以证明这不会导致问题。 Although I do agree that using commonmodule and sharedmodule makes the modules more modular. 虽然我同意使用commonmodule和sharedmodule使模块更加模块化。

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

I have lazy loading modules similar to the example. 我有类似于示例的延迟加载模块。 Let me know if this does not solve the issue for you. 如果这不能解决您的问题,请告诉我。 I have played around with this problem for quite some time and probably will be able to help by recreating the issue again. 我已经玩了很长一段时间来解决这个问题,并且可能会通过再次重现这个问题来提供帮助。

What you are asking for is a static property in your Service. 您要求的是您的服务中的static属性。 Otherwise, it is working as expected. 否则,它按预期工作。 If you want to make a property of your service singleton throughout, declare it like this in your service, 如果您想在整个服务中创建一个属性,请在服务中声明如下:

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 I am sorry, just re-read your question, it is behaving as expected. 哦,对不起,只是重新阅读你的问题,它表现得像预期的那样。 Since you have this.Param = "Not Set"; 既然你有this.Param = "Not Set"; in the constructor of your service, everytime you switch between your components, it forces the instantiation of this singleton service again in your component (through the constructor's argument in your component) which in turn makes the constructor of service called again and thus reverts back the Param 's value to "Not Set" . 在您的服务的构造函数中,每次在组件之间切换时,它会强制在组件中再次实例化此单例服务(通过组件中的构造函数的参数),这反过来又会使服务的构造函数再次调用,从而恢复Param"Not Set"的价值。 Makes sense? 说得通?

EDIT-2 编辑-2

Answering to your comment, it is due to the dependency injection of the service into the component done through its (component's) constructor. 回答你的评论,这是由于通过其(组件)构造函数将服务依赖注入到组件中。

In short, injecting the service like this, 简而言之,注入这样的服务,

constructor(private starService: StarService) { }

as per the docs , 按照文档

A provider is something that can create or deliver a service. 提供者可以创建或提供服务。 Angular creates a service instance from a class provider by using new . Angular使用new从类提供程序创建服务实例。

will under the hood assign the private starService property to, private starService属性,

private starService = new StarService();

which will call the service's constructor. 这将调用服务的构造函数。

If you don't want any default actions to happen every time the service is injected, then don't perform any property assignments within its (service's) constructor. 如果您不希望每次注入服务时都发生任何默认操作,则不要在其(服务)构造函数中执行任何属性赋值。

And, every time you switch between components through its routes, the corresponding component gets created by calling its constructor and the corresponding lifecycle hooks it has implemented. 并且,每次通过其路由在组件之间切换时,通过调用其构造函数和它已实现的相应生命周期钩子来创建相应的组件。 Hence it will also create the corresponding dependencies defined within their constructors as well. 因此,它也将创建在其构造函数中定义的相应依赖项。 Hope it makes sense now. 希望现在有意义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM