Reputation: 4237
I have a large complex AngularJS Comet application ("real-time"). Clients send data to the server, and also receive notifications from the server about events other users have initiated.
In its simplest form, the app has these client-side components ("Service" below could be AngularJS .service or .factory, whatever)
[Object] Controller
: could be any object, like Student
, Teacher
, Lesson
, Document
[Object] Service
: holds model of the object and has methods to operate on that dataSocket Service
: wrapper for socket libraryCalls can go both directions
[Object] Controller
> [Object] Service
> Socket Service
> ServerSocket Service
> [Object] Service
> [Object] Controller
> User NotifiedWhat is the best architecture for two-way inter-module communication in this case?
Here's what I think are the options. Please suggest other good ones if I've left them out.
[Object] Controller
makes a call to [Object] Service
, which returns a promise and in turn calls Socket Service
that also returns a promise, and when Socket Service
receives some data, the promise resolves back up the chain, at which point [Object] Controller
initiates another request.Upvotes: 1
Views: 994
Reputation: 1817
A clean solution would be to use classical DI for the user initiated direction. Since your [Object] Service contains the model you only need to update that (if you implementation is otherwise clean, i.e. you use the injected model object everywhere).
So the problem is reduced to how to get the new updates from your Socket Service to the [Object] Service. Since your Socket Service actually should not know about your Models Details injection of the models is not a reasonable solution (leave alone the so created circular dependency). Recieving an update from a server for anything in your client app is in in the very definition an event (can occure at any time), so I think it is very reasonable to get the $RootScope
in your SocketService and broadcast it. On this event your [Object] Services take than care for updating the models based on the new information.
If you have many services and usually the server initiated events are only relevant to one or very few of them, a possible optimization would be to sent the a field from the server which models are affected by this update. This is reasonable, since the server knows about the models already and it enables the Socket Service to broadcast updateFor:xxx events without knowing about what xxx means. The respective [Object] service then listens only to the updateFor:[Object] event. But as always with optimizations, do not do them if the easy way already works for you.
Upvotes: 1