如何顺序创建动态组件的多个实例?

How to create multiple instances of a dynamic component sequentially?

我有一个 SystemMessageService,它使用以下方法创建 SystemMessageComponent 的实例

createSystemMessage(message: string, vcr: ViewContainerRef, time: number = 4500, isErrorMessage: boolean = false, isWarningMessage: boolean = false, isSuccessMessage: boolean = false){
    let systemMessageCmpFactory = this.componentFactoryResolver.resolveComponentFactory(SystemMessageComponent);
    this.hostViewContainerRef = vcr;
    this.hostViewContainerRef.clear();
    this.systemMessageCmpRef = this.hostViewContainerRef.createComponent(systemMessageCmpFactory);
    this.systemMessageCmpRef.instance.message = message;
    this.systemMessageCmpRef.instance.timeUntilDestruction = time;
    this.systemMessageCmpRef.instance.isErrorMessage = isErrorMessage;
    this.systemMessageCmpRef.instance.isWarningMessage = isWarningMessage;
    this.systemMessageCmpRef.instance.isSuccessMessage = isSuccessMessage;
    this.closeSubMsg = this.systemMessageCmpRef.instance.closeMessage.subscribe(() => {
      this.closeSubMsg.unsubscribe();
      this.hostViewContainerRef.clear()
    })
  }

现在我在 SystemMessageService

中有一个通知程序
private systemMessageNotifier$: Subject<string> = new Subject();
public systemMessageObs$ = this.systemMessageNotifier$.asObservable();
emitSystemMessage(systemMessage: string){
    this.systemMessageNotifier$.next(systemMessage);
}

通知app.component.ts何时显示新系统消息

@ViewChild('systemMessageHost', {read: ViewContainerRef}) systemMessageHost: ViewContainerRef;
  constructor(private systemMessageService: SystemMessagesService){

  }

  ngOnInit(): void {
    this.systemMessageService.systemMessageObs$.subscribe(systemMessage => {
      this.systemMessageService.createSystemMessage(systemMessage, this.systemMessageHost, 60*1000*60)
    })
  }

但问题是如果按顺序发送消息会重叠,例如如果我在任何组件中调用以下内容

this.systemMessageService.emitSystemMessage("Message1");
this.systemMessageService.emitSystemMessage("Message2");

我只会显示“Message2”,但我想先显示“Message1”,如果用户关闭该组件,则应在之后显示“Message2”。我将如何实施? SystemMessageComponent可以通过超时或单击关闭按钮关闭。

我是这样解决的:我用一个变量来检查一个实例是否存在。如果存在,我将下一条消息推送到数组中。当实例被销毁时,我使用通知程序通知 app.component 实例已被销毁,这样,如果有另一条消息,可以显示下一条消息。

private systemMessageNotifier$: Subject<SystemMessage> = new Subject();
public systemMessageObs$ = this.systemMessageNotifier$.asObservable();
private sysMsgDestroyedNotifier$: Subject<any> = new Subject();
public systemMessageDestroyed$ = this.sysMsgDestroyedNotifier$.asObservable();

createSystemMessage(message: string, vcr: ViewContainerRef, messageType: SystemMessageType, noTimeOut: boolean = false, timeUntilDestruction: number = 1000*3600){
    let systemMessageCmpFactory = this.componentFactoryResolver.resolveComponentFactory(SystemMessageComponent);
    this.hostViewContainerRef = vcr;
    this.hostViewContainerRef.clear();
    this.systemMessageCmpRef = this.hostViewContainerRef.createComponent(systemMessageCmpFactory);
    this.systemMessageCmpRef.instance.message = message;
    this.systemMessageCmpRef.instance.timeUntilDestruction = timeUntilDestruction;
    this.systemMessageCmpRef.instance.messageType = messageType;
    this.systemMessageCmpRef.instance.noTimeOut = noTimeOut;
    this.closeSubMsg = this.systemMessageCmpRef.instance.closeMessage.subscribe(() => {
      this.closeSubMsg.unsubscribe();
      this.hostViewContainerRef.clear();
      this.sysMsgDestroyedNotifier$.next();
    })
  }
export class AppComponent implements OnInit {
  delayedSystemMessages = [];
  isSystemMessageComponentActive: boolean = false; 
  @ViewChild('systemMessageHost', {read: ViewContainerRef}) systemMessageHost: ViewContainerRef;
  constructor(private systemMessageService: SystemMessagesService){

  }

  ngOnInit(): void {
    
    this.systemMessageService.systemMessageDestroyed$.subscribe(() => {
      if(this.delayedSystemMessages.length > 0){
        this.isSystemMessageComponentActive = false;
        let message = this.delayedSystemMessages.shift()
        this.systemMessageService.emitSystemMessage(message);
      }
    })

    this.systemMessageService.systemMessageObs$.subscribe(systemMessage => {
      if(this.isSystemMessageComponentActive){
        this.delayedSystemMessages.push(systemMessage)
        return;
      }
      this.isSystemMessageComponentActive = true;
      this.systemMessageService.createSystemMessage(systemMessage.message, this.systemMessageHost, systemMessage.messageType, systemMessage.noTimeOut, systemMessage.timeUntilDestruction)
    })
  }
}