Reputation: 997
i have 4 components in same components level;
i called them A , B , C ,D
here is my index.html:
<A><A>
<B></B>
<C></C>
<D></D>
now i have a service E;
A and B wants to share E's instance e-one,
C and D wants to share E's another instance e-two,
how to inject this service ,thanks!,
ps: i have known how to share service between two component by module or with in same parent component
Upvotes: 2
Views: 2270
Reputation: 6284
Angular has three provider scopes - root, module and component. As you already know, root & module scopes are too broad, which leaves us with the component scope. You can actually use it to get the desired behaviour.
Let's only take components A and B for this example. One of these (let's choose A) has to take on the "master" role and inject the desired service, whilst making it publicly accessible. The other component (B) can then simply access the service as A's public member instead of injecting (and thus creating a separate instance of) the service itself. In code it would look like this:
Component A
@Component({
selector: 'A',
template: ''
})
export class ComponentA {
constructor(public serviceE: ServiceE) {}
}
Component B
@Component({
selector: 'B',
template: ''
})
export class ComponentB {
@Input()
serviceE: ServiceE;
}
Parent
<A #componentA><A>
<B [serviceE]="componentA.serviceE"></B>
This is a modified version of this example from the docs: https://angular.io/guide/component-interaction#parent-interacts-with-child-via-local-variable.
You'd do exactly the same thing with components C & D - they'd share their own separate instance of E.
I would like to note that while this seems perfectly legal to me, there might be better ways of achieving whatever goal you had.
E.g. if one of the components is more "main/central" (think table) than the other (think table footer), then instead of taking the whole instance of the service, the lesser component (the footer) might could do away with only a small part of the service's data/functionality. You could just expose those using exactly the same pattern, which would result in better encapsulation. In the table/table footer case, the footer only needs to expose some (pageChange) events and maybe take some inputs, e.g. [totalDocumentCount], instead of accessing the whole instance of the service.
Upvotes: 0
Reputation: 47
Create a shared service to handle stuff between components
storage.service.ts
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
@Injectable()
export class StorageService {
data$:Subject<any> = new Subject<any>();
constructor () { }
}
component A (Setter/Sender)
this.storageService.data$.next('Message to send, you can pass data');
component B (Getter/Reciever)
this._subscription = this.storageService.data$.subscribe( data => {
this.data = data;
});
Upvotes: 2