问题
As per the single-spa official doc, we can share the application's UI state by using RxJs.
Observables / Subjects (RxJs) - one microfrontend emits new values to a stream that can be consumed by any other microfrontend. It exports the observable to all microfrontends from its in-browser module, so that others may import it.
Link: https://single-spa.js.org/docs/recommended-setup/#ui-state
Link: https://single-spa.js.org/docs/faq/#how-can-i-share-application-state-between-applications
I was trying to create an example in React, where I am using single-spa parcel to include my micro-apps in root application. I was trying to share the UI state using RxJs. When I googled it for single-spa RxJs, I didn't find anything. Can anyone provide me a basic example where I will be able to share UI state for below use cases:
- Sharing the UI state from root app to my micro-apps.
- Sharing the UI state from micro-apps to root apps.
- Sharing the UI state between micro-apps.
回答1:
Here is a high level overview on how to approach this:
add rxjs as a shared dependency in your import map
"rxjs": 'https://unpkg.com/@esm-bundle/rxjs/system/rxjs.min.js, "rxjs/operators": 'https://unpkg.com/@esm-bundle/rxjs/system/rxjs-operators.min.js,
- consider pinning these to a specific version!
create a utility module (create-single-spa makes this easy!) that sets up and exports the observable with data that you need
include this utility module in importmap too
import and subscribe to observable from the utility module in the apps that need it
- don't forget to unsubscribe when your apps unmount.
celebrate 🎉
I have created single-spa-example-rxjs-shared-state as an example repo that shows how to use an Rxjs utility module with cross-frontend imports.
回答2:
This does the trick In root html js file add the following
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();
})
In component
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();
}
}
Take look at the following repo, handled the same scenario by passing observable ref to micro apps through customprops of single spa
https://github.com/SENTHILnew/micro_spa_intercom
来源:https://stackoverflow.com/questions/61500732/how-to-share-ui-state-in-single-spa-using-rxjs