当我在 BehaviorSubject 上调用函数 next 时,订阅函数没有被触发

Subscribe function is not trigger when I call function next on BehaviourSubject

我有 2 个组件和一个在这 2 个组件之间共享的服务,比方说 ComponentA 和 ComponentB。应用程序工具栏的一个组件 (Comp. A) 和另一个组件 B,使用路由模块进行路由。这是 HTML:

<a></a>
<router-outlet></router-outlet>

之所以采用这种方式,是因为我希望始终将工具栏固定在顶部。 在组件 A 的 HTML 中,我有一个 select 到 select 应用程序的语言。在组件 B 中,我有一些来自后端的内容,具体取决于 selected language.I 希望当用户更改语言时,内容来自服务器,rendered.I 正在使用该服务调用后端并呈现新内容。我的问题来了,对服务器的调用已经完成并且没问题,但它从未进入订阅功能。我曾尝试使用共享模块(有或没有 forRoot()),我试图使该服务成为模块的提供者,并在另一个模块(AppModule)中导入模块(AppRoutingModule)。在这一刻,我到了控制台出现 "No provider for Service!" 错误的地步。服务和组件的代码: 服务:

@Injectable()
export class SharedService extends GlobalHttpService<HomeSection> {
  private sectionsSubject: BehaviorSubject<HomeSection[]>;
  constructor(private http: HttpClient) {
    super("api/path", new GlobalSerializer(HomeSection), http);
    this.sectionsSubject = new BehaviorSubject<HomeSection[]>([]);
  }

  load() {
    this.list().subscribe(res => {
      this.sectionsSubject.next(res);
    });
  }
  get content() {
    return this.sectionsSubject.asObservable();
  }
}

AppModule

@NgModule({
 imports:[AppRoutingModule]
})
export class AppModule {}

AppRoutingModule

export function SharedServiceFactory(http: HttpClient){
  return new SharedServiceFactory(http);
}

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
  providers: [
    {
      provide: SectionService,
      useFactory: SectionServiceFactory,
      deps: [HttpClient]
    }
  ]
})
export class AppRoutingModule {}

组件A:

@Component({
  selector: "a",
  templateUrl: ".a.component.html",
  styleUrls: ["./a.component.scss"]
})
export class AComponent implements OnInit {
  constructor(
    public authentificationService: AuthenticationService,
    private languagesService: LanguagesService,
    private sharedService: SharedService
  ) {
  }
 ngOnInit() {
//other logic;
}

updateLanguage(event) {
// other logic;
this.sharedService.load();
}

组件B

@Component({
  selector: "app-b",
  templateUrl: "./b.component.html",
  styleUrls: ["./b.component.scss"]
})
export class BComponent implements OnInit {
  constructor(
    private sharedService: SharedService,
  ) {}

ngOnInit() {
 this.sharedService.load();
 this.sharedService.content.subscribe(s => {
 // logic
 });
}

如何才能拥有 SharedService 的单个实例,或者我能否将一个模块包含在另一个模块中?

尝试在您的服务中这样做:

@Injectable({ providedIn: 'root' })

并从 A​​ppRoutingModule 中删除提供此服务。 如果您使用 providedIn: 'root',则无需在其他地方提供。它将在 Angular 树的最顶端注入服务,因此您将始终拥有相同的实例。它的另一个好处 - 它使服务可摇树。

首先在AppModule中导入服务:

AppModule

@NgModule({
 imports:[AppRoutingModule],
 providers: [SharedService]
})
export class AppModule {}

或:

@Injectable({ providedIn: 'root' }) 导出 class SharedService 扩展 GlobalHttpService { ... }

然后,您不必在 SharedService 中创建一个方法来 return Observable 事件,您可以只在构造函数中创建一个 属性 和实例一次。

SharedService

@Injectable()
export class SharedService extends GlobalHttpService<HomeSection> {
  private sectionsSubject: BehaviorSubject<HomeSection[]>;
  public content$: Observable<HomeSection[]>;
  constructor(private http: HttpClient) {
    super("api/path", new GlobalSerializer(HomeSection), http);
    this.sectionsSubject = new BehaviorSubject<HomeSection[]>([]);
    this.content$ = this.sectionsSubject.asObservable();
  }

  load() {
    this.list().subscribe(res => {
      this.sectionsSubject.next(res);
    });
  }
}

最后在你的组件 B 中:

@Component({
  selector: "app-b",
  templateUrl: "./b.component.html",
  styleUrls: ["./b.component.scss"]
})
export class BComponent implements OnInit {
  constructor(
    private sharedService: SharedService,
  ) {}

ngOnInit() {
 this.sharedService.load();
 this.sharedService.content$.subscribe(s => {
     // logic
 });
}