用Angular Service 和 RxJS Subject实现消息显示

网页应用中经常需要用对话框组件或者Toast组件显示信息。通常做法是在需要用到的页面html里增加相应语句,并在该页面的ts文件里调用。考虑到这两组件使用比较频繁,为避免在各个页面重复编程,可以将这两组件加到框架页面里,这样框架页面组件下的所有组件都可以使用了。在子组件里要调用框架页面的功能,就属于跨组件通信。这时RxJS 的Subject就可以发挥重要作用了。

1、先是创建一个可注入所有组件的服务,比如名为 FrameworkService

@Injectable({
    providedIn: 'root',
})
export class FrameworkService {
      //定义Subject 用于弹出messagebox
      private msgbox = new Subject<string>;
      msgbox$ = this.msgbox.asObservable();

      showMessageBox(info:string) {
           this.msgbox.next(info)
    }
}

@Injectable 声明FrameworkService是可注入的类,providedIn: ‘root’ 表示可以在全局注入

上面代码在FrameworkService中定义了一个msgbox$ Observable,用于表明有弹出消息对话框的需求,该Observable 观测对象是想显示出来的消息字符串。

2、在框架页面FrameworkComponent中定义msgbox

html中插入自定义的msgbox 或Toast组件。这里推荐使用 primeng 的 Toast 组件。

<app-msgbox #msgbox></app-msgbox>

在ts中定义msgbox

import { OnDestroy, ViewChild  } from '@angular/core';
//导入FrameworkService
import { FrameworkService } from "src/app/service/framework.service";
//导入自定义的msgbox组件,路径是你的组件文件位置
import { MessageBoxComponent } from 'src/app/components/messagebox/messagebox.component';

export class FrameworkComponent implements OnDestroy {
     //用于取消注册
     private msgboxSubscription:Subscription

     // 通过模板变量名msgbox获取html中messagebox 组件实例
     @ViewChild('msgbox') msgBox: MessageBoxComponent; 

     constructor(public frameworkService: FrameworkService, ... ) {
           //订阅 FrameworkService 中 msgbox$ 
           // 当有消息时,则显示该消息
           this.msgboxSubscription=this.FrameworkService.msgbox$.subscribe((v)=> {
               this.msgBox.show(v)
           })
     }

    ngOnDestroy() {
        //组件退出时,取消订阅
        if (this.msgboxSubscription) {
            this.msgboxSubscription.unsubscribe()
        }
    }
    
    ... ... 
}

在module中导入MessageBoxComponent.module

import { MessageboxComponentModule } from 'src/app/components/messagebox/messagebox.component.module';

@NgModule({
    declarations: [
        ...
    ],
    imports: [
        ...
        MessageboxComponentModule,
    ],
    exports: [FrameworkComponent]
})

3、最后,就可以在任一与FrameworkComponent共存的组件中调用FrameworkService的showMessageBox函数了。

//导入FrameworkService
import { FrameworkService } from "src/app/service/framework.service";

export class XXX  {
     constructor(public frameworkService: FrameworkService, ... ) {
          ... 
     }

     YYY()  {
          //在需要的地方调用
          this.frameworkService.showMessageBox("显示消息成功")
     }
}

发表评论