问题
I just started learning about angular 2 and I am having questions on if the scenario I think is possible.
I have a micro service model where in I have angular apps associated to each micro service.
- Microservice 1 & ng app 1 - is for handling the transactions of the user
- service 2 and ng app 2 - is to calculate all applicable taxes for the user
If I land on app 1, enter the details of my transaction and click a continue button, I should be able to pass "All" the values that are required for tax calculation along with the user Id?
Passing it through URL should work but i have user ID, transactionID, transaction amount etc to be bit secure.
Would I be able to pass it through ngOnInit() or through some life cycle event so that ng app 2 gets those details and the page loads with the tax values based on the init params passed? Help me on this :)
回答1:
Well, what you seem to have is Microfrontends. Just like each microservice is designed for a very specific entity, each micro frontend is designed for a very specific entity. And that's what you seem to have.
A very common approach of sharing data between micro frontends is by defining custom events.
A micro frontend(A) can emit an event like this:
// this is attached to the button in micro-frontend A
btn.onclick = () => {
const event = new Event("a__click");
window.dispatchEvent(event);
};
Another micro frontend(B) can listen to that event and react accordingly:
// fire this when the micro-frontend initializes
window.addEventListener("a__click", () => this.onUpdateCount());
// actual method to update the count
onUpdateCount(amt = 1) {
this.state.count += amt;
const countEl = this.shadowRoot.getElementById("b__count");
countEl.innerHTML = this.state.count;
}
Here's an amazingly enlightening article on Medium by a guy named Benjamin Johnson that you might want to read to know more about it.
That being said, since these are DOM Events, someone could still intercept them somehow. In those cases, you could have a custom microservice implemented that could return a particular sensitive information and then do the needful with that.
回答2:
I was also worked on the same kind of Architecture using single-spa meta framework . What I did was I have created my own dispatcher utility using plain Javascript(Reusable API) using RxJS , because any way Angular have a dependency of RxJS. So we can take the advantage of it.
Here is the code I have implemented , You can publish and subscribe from any micro front end applications(Angular,React,Vue.js). The code I have written in ts. You can convert to js if you want.
import { Subject } from "rxjs";
(function (global: any) {
var RxDispatcher: any = function () {
return new RxDispatcher.instance();
};
RxDispatcher.prototype = {
getDispatcher: function (dispatcherName: string): Subject<any> {
if (global.subjects) {
return global.subjects[dispatcherName]
? global.subjects[dispatcherName]
: console.error(
"Unable to find the dispatcher of " +
dispatcherName +
" .Please ensure the dispatchers are properly registered."
);
}
console.error(
"Unable to find the dispatcher of " +
dispatcherName +
" .Please ensure the dispatchers are properly registered."
);
},
registerDispatchers: function (dispatchers: string[]) {
if (dispatchers) {
if (!global.subjects) {
global.subjects = {};
}
dispatchers.forEach(dispatcher => {
if (!global.subjects[dispatcher]) {
global.subjects[dispatcher] = new Subject();
}
});
}
},
dispatch: function (dispatcher: string, args?:any): void {
if (!dispatcher) {
console.error(
"Unable to dispatch message to dispatcher of " + dispatcher
);
} else {
var dispatcherInstance = this.getDispatcher(dispatcher);
if (dispatcherInstance) dispatcherInstance.next(args);
}
},
dispatchToMultiple: function (dispatchers: string[],args?:any) {
if (!dispatchers) {
console.error(
"Unable to dispatch message to dispatcher of " + dispatchers
);
}
dispatchers.forEach(subscriber => {
var dispatcherInstance = this.getDispatcher(subscriber);
if (dispatcherInstance) dispatcherInstance.next(args);
});
},
clear: function () {
delete global["subjects"];
}
};
RxDispatcher.instance = function () { };
RxDispatcher.instance.prototype = RxDispatcher.prototype;
global.RxDispatcher = RxDispatcher;
})(window);
Usage
if you are in typescript , you have to declare
declare var RxDispatcher: any;
Register Dispatchers
var dispatchers=["onSendMessage"]
RxDispatcher().registerDispatchers(dispatchers); //expecting an array.
You can register multiple dispatchers at one time
Send Message
RxDispatcher().dispatch("onSendMessage", {
message: "Hi"
})
Subscribe Message
RxDispatcher().getDispatcher("onSendMessage")
.subscribe((message) => {
console.log(message) //Output : Hi
});
来源:https://stackoverflow.com/questions/53397918/passing-param-to-ngoninit-through-service