1

根据 single-spa 官方文档,我们可以使用 RxJs 共享应用程序的 UI 状态。

Observables / Subjects (RxJs) - 一个微前端向流中发出新值,任何其他微前端都可以使用这些值。它将可观察对象从其浏览器内模块导出到所有微前端,以便其他人可以导入它。

链接:https ://single-spa.js.org/docs/recommended-setup/#ui-state

链接:https ://single-spa.js.org/docs/faq/#how-can-i-share-application-state-between-applications

我试图在 React 中创建一个示例,其中我使用 single-spa 包裹将我的微应用程序包含在根应用程序中。我试图使用 RxJs 共享 UI 状态。当我用谷歌搜索单水疗 RxJs 时,我什么也没找到。谁能给我一个基本示例,我将能够为以下用例共享 UI 状态:

  • 将 UI 状态从根应用程序共享到我的微应用程序。
  • 将 UI 状态从微应用共享到根应用。
  • 在微应用之间共享 UI 状态。
4

2 回答 2

6

以下是有关如何处理此问题的高级概述:

  • 在导入映射中添加 rxjs 作为共享依赖项

      "rxjs": 'https://unpkg.com/@esm-bundle/rxjs/system/rxjs.min.js,
      "rxjs/operators": 'https://unpkg.com/@esm-bundle/rxjs/system/rxjs-operators.min.js,
    
    • 考虑将这些固定到特定版本!
  • 创建一个实用模块(create-single-spa让这一切变得简单!),使用您需要的数据设置和导出 observable

  • 将此实用程序模块也包含在 importmap 中

  • 从需要它的应用程序中的实用程序模块导入和订阅 observable

    • 当您的应用程序卸载时,不要忘记取消订阅。
  • 庆祝

我创建了single-spa-example-rxjs-shared-state作为示例 repo,它展示了如何使用带有跨前端导入的 Rxjs实用程序模块

于 2020-04-30T20:27:30.270 回答
1

这可以解决问题在根 html js 文件中添加以下内容

Import { Subject, Subscription } from 'https://dev.jspm.io/rxjs@6/_esm2015';
import { filter, map } from 'https://dev.jspm.io/rxjs@6/_esm2015/operators';

export class EventBusService {


  constructor() {this.subject$ = new Subject(); }

  emit(event) {
    this.subject$.next(event);
  }

  on(eventName, action) {
    return this.subject$.pipe(
      filter( (e) => e.name === eventName),
      map( (e) => e["data"])).subscribe(action);
  }
}

var EventBus= new EventBusService()`enter code here`;



System.import('single-spa').then(function (singleSpa) {

    singleSpa.registerApplication(
      'app1',
      function () {
        return System.import('app1');
      },
      function (location) {
        return true;
       // return location.pathname.startsWith('/app1');
      },
      { EventBus: EventBus }
    );

    singleSpa.registerApplication(
      'app2',
      function () {
        return System.import('app2');
      },
      function (location) {
       return true
        // return location.pathname.startsWith('/app2');
      },
      { EventBus: EventBus }
    )

    singleSpa.start();
  })

在组件中

import { Component,OnInit ,ChangeDetectorRef} from '@angular/core';
import { assetUrl } from 'src/single-spa/asset-url';
import { singleSpaPropsSubject, SingleSpaProps } from 'src/single-spa/single-spa-props';
import { Subscription } from 'rxjs';
@Component({
  selector: 'app1-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit  {

  singleSpaProps: SingleSpaProps;
  subscription: Subscription;
  title = 'app1';
  yoshiUrl = assetUrl("yoshi.png");
  msgFromMicro="";
  titleToPass="";
  constructor(private ChangeDetectorRef:ChangeDetectorRef){

  }
  ngOnInit(): void {
    this.subscription = singleSpaPropsSubject.subscribe(
      props => {
        this.singleSpaProps = props;
        console.log(props);
        this.lookForEvents();
      }
    );
  }
  lookForEvents(){
    this.singleSpaProps['EventBus'].on('msgFrmMicro2',(data)=>{
      this.msgFromMicro=data;
      this.ChangeDetectorRef.detectChanges();
    });
  }
  sendMsg(){
   // alert(this.titleToPass);
   debugger;
   this.singleSpaProps['EventBus'].emit({name:'msgFrmMicro1',data:this.titleToPass});
  }
  ngOnDestroy(): void {
    this.subscription.unsubscribe();
  }
}

看看下面的 repo,通过单个 spa 的 customprops 将 observable ref 传递给微应用程序来处理相同的场景

https://github.com/SENTHILnew/micro_spa_intercom

于 2020-06-10T15:58:05.773 回答