Angular 7个共享服务未共享

Angular 7 shared service is not shared

我是 angular 的新手,我想在导航后将数据从一个组件 (HomeComponent) 传递到另一个组件 (ProfileComponent)。

我创建了一个共享服务(DataService)。 我在 HomeComponent 和 ProfileComponent 中都注入了服务,但是当我在 HomeComponent 中设置消息的值 属性 并尝试在 ProfileComponent 中检索它时,该值是未定义的,因为 DataService 不是同一个实例。

DataService 已在 providers 数组中的 AppModule 中注册,因此它应该是共享服务并且始终是相同的实例,对吧?

提前致谢

DataService.ts

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class DataService {

  message:string;

  constructor() { }
}

HomeComponent.ts

import { Component, OnInit } from '@angular/core';
import { DataService } from '../services/data/data.service';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {

  constructor(private data:DataService) { }

  ngOnInit() {
    this.data.message = "hello world";
  }

}

ProfileComponent.ts

import { Component, OnInit } from '@angular/core';
import { DataService } from '../services/data/data.service';

@Component({
  selector: 'app-profile',
  templateUrl: './profile.component.html',
  styleUrls: ['./profile.component.css']
})
export class ProfileComponent implements OnInit {

  private message : string;//undefined

  constructor(private data:DataService) { }

  ngOnInit() {
    this.message = this.data.message;
  }

}

AppModule.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { DataService } from './services/data/data.service';
import { HomeComponent } from './home/home.component';
import { ProfileComponent } from './profile/profile.component';

@NgModule({
  declarations: [
    AppComponent,
    HomeComponent,
    ProfileComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule
  ],
  providers: [DataService],
  bootstrap: [AppComponent]
})
export class AppModule { }

每次将服务注入组件时,都会生成新实例。但是在这种情况下,我建议您按如下方式使用 BehaviorSubject,

@Injectable()
export class SharedService {
  private messageSource = new BehaviorSubject<string>("default message");
  currentMessage = this.messageSource.asObservable();

  constructor() { }

  changeMessage(message: string) {
    this.messageSource.next(message)
}

STACKBLITZ DEMO

我知道这是一个 2 年的问题,但 Google 将它放在搜索结果的顶部

现在,Angular 文档对此更加清楚(或者我们可以更容易地找到它),它被称为“Singleton Services” 解释此“错误”的部分是 The ForRoot Pattern,它说:

"如果一个模块同时定义了提供者和声明(组件、指令、管道),那么在多个功能模块中加载该模块将重复服务的注册。这可能会导致多个服务实例,并且服务不会不再表现为单例。"

综上所述,如果您在服务中定义此 (DataService.ts),providedIn: root 如下

@Injectable({ providedIn: 'root' })

您需要避免将服务定义为组件或模块上的提供者。

AppModule.ts

...
imports: [
    BrowserModule,
    AppRoutingModule
  ],
  providers: [DataService], // This line is the problem
  bootstrap: [AppComponent]
....

希望对某人有所帮助,如果需要更多文档,请参阅 Singleton Services' link