首页 > 解决方案 > 组件之间无法通信事件

问题描述

我有这个充当调解员的课程:

 export class ProgressBarService {

  // Observable string sources
  private progressAnnouncement = new Subject<number>();

  // Observable string streams
  progressAnnounced$ = this.progressAnnouncement.asObservable();

  constructor() { }

  AdministerProgress(progress: number) {
    this.progressAnnouncement.next(progress);
  }
}

组件 A 在 ngOnInit 中发送如下消息:

  this.progressBarService.AdministerProgress(100);

但它永远不会到达导航组件:

 constructor(private breakpointObserver: BreakpointObserver,
    private requestBuilder: RequestBuilder,
    private cdref: ChangeDetectorRef,
    private router: Router,
    private progressBarService: ProgressBarService ) {
    
  }

  ngOnInit(): void {
 
  }

  ngAfterContentChecked() {
    this.progressBarService.progressAnnounced$.subscribe(announcement => {
      console.log(announcement);
      this.progressBarValue = announcement;
      this.cdref.detectChanges();
    });
  }

我没有收到有关 console.log 的消息。这是为什么? 更新 我遵循了这个解释 行为主题

    import { Injectable } from '@angular/core';
import { BehaviorSubject, Subject } from 'rxjs';

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

  // Observable string sources
  public progressAnnouncement$ = new BehaviorSubject(0);


  constructor() { }

  AdministerProgress(progress: number) {
    console.info('inside func',progress);
    this.progressAnnouncement$.next(progress);
  }
}

首先加载的页面的导航标题订阅:

    ngAfterContentChecked() {
    this.progressBarService.progressAnnouncement$.subscribe(announcement => {
      console.info('Announcement', announcement);
      this.progressBarValue = announcement;
      this.cdref.detectChanges();
    });
  }

然后另一个稍后加载的组件使用 AdministerProgress 函数发出值,如下所示:

    this.progressBarService.AdministerProgress(100);

标头组件永远不会收到 100 值。它得到的只是一个接一个的许多 0 值。

更新:

这是共享类:

    import { Injectable } from '@angular/core';
import { BehaviorSubject, Subject } from 'rxjs';

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

  public progressAnnouncement$ = new BehaviorSubject(0);
  constructor() { }

  AdministerProgress(progress: number) {
    this.progressAnnouncement$.next(progress);
  }
}

这是我创建的单例模块,如此链接中所述:

https://angular.io/guide/singleton-services#providing-a-singleton-service

    import { ModuleWithProviders, NgModule, Optional, SkipSelf } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ProgressBarService } from 'app/Services/Classes/ProgressBarServices/ProgressBarService';



@NgModule({
  declarations: [],
  imports: [
    CommonModule
  ]
})
export class SingletonModule {

  constructor(@Optional() @SkipSelf() parentModule?: SingletonModule) {
    if (parentModule) {
      throw new Error(
        'SingletonModule is already loaded. Import it in the AppModule only');
    }
  }

  static forRoot(): ModuleWithProviders<SingletonModule> {
    return {
      ngModule: SingletonModule,
      providers: [
        ProgressBarService
      ]
    };
  }
}

这是我导入该模块的 app.module 的部分:

  imports: [
CommonModule,
BrowserModule,
AppRoutingModule,
BrowserAnimationsModule,
MatsharedModule,
HttpClientModule,
SharedModule,
PrimeNGModule,
LayoutModule,
SingletonModule.forRoot(),

这是我的主要 AppRoutingModule 配置文件:

    import { NgModule } from '@angular/core';
import { Routes, RouterModule, PreloadAllModules } from '@angular/router';
import { DashboardComponent } from './Dashboard/dashboard/dashboard.component';
import { PageNotFoundComponent } from './Errors/page-not-found/page-not-found.component';
import { AuthGuard } from './Services/Guards/auth.guard';


const routes: Routes = [
  {
    path: 'dashboard',
    component: DashboardComponent,
    canActivate: [AuthGuard]
  },
  {
    path: 'authentication',
    loadChildren: () => import('./authentication/authentication.module').then(m => m.AuthenticationModule)
  },
  {
    path: 'accounting',
    loadChildren: () => import('./accounting/accounting.module').then(m => m.AccountingModule),
    canActivate: [AuthGuard]
  },
  {
    path: 'users',
    loadChildren: () => import('./users/users.module').then(m => m.UsersModule),
    canActivate: [AuthGuard]
  },
  {
    path: 'game-management',
    loadChildren: () => import('./game-management/game-management.module').then(m => m.GameManagementModule),
    canActivate: [AuthGuard]
  },
  {
    path: 'operator',
    loadChildren: () => import('./operator-management/operator-management.module').then(m => m.OperatorManagementModule),
    canActivate: [AuthGuard]
  },
  {
    path: 'technical',
    loadChildren: () => import('./technical/technical.module').then(m => m.TechnicalModule),
    canActivate: [AuthGuard]
  },
  {
    path: '404',
    component: PageNotFoundComponent
  },
  {
    path: '',
    redirectTo: 'dashboard',
    pathMatch: 'full'
  },
  {
    path: '**',
    redirectTo: '404',
    pathMatch: 'full'
  }
];

@NgModule({
  imports: [RouterModule.forRoot(routes,
   {
   // enableTracing: true,// <-- debugging purposes only
    preloadingStrategy: PreloadAllModules
  }
  )],
  exports: [RouterModule]
})
export class AppRoutingModule { }

另一个模块没有提供的服务或导入的单例模块的​​痕迹。

我相信我错过了一些配置。

标签: angular

解决方案


很可能是在触发数据navigation component后订阅了 Observable component A,这意味着它错过了数据。

progressAnnouncement解决方案是从更改SubjectBehaviorSubjectReplaySubject。这两者的用途略有不同,但主要区别Subject在于它们将数据存储在内部,而新订阅者总是拥有最新的数据(BehaviorSubject)或发出的所有数据(ReplaySubject)。

更新 :

在延迟加载的情况下,两个组件使用相同服务的不同实例会改变,最简单的方法是将服务标记为应用程序范围的单例使用@Injectable({providedIn: 'root'})模式。您可以在此处阅读有关 Angular 中的单例服务的更多信息


推荐阅读