Reputation: 107
getting issue in component data sharing. i have 2 components, they don't have parent child relationship. in my sidebar component i have a checkbox, by clicking this checkbox i want to perform some action in my dashboard component.
sidebar component
manageWidgetLocation(){
this.togglewidgetService.toggleSideNav(true);
}
dashboard component
ngOnInit(): void {
this.togglewidgetService.onSideNavToggle()
.subscribe(
(opening) => {
debugger;
if (opening) {
console.log(">>>>>>>here");
} else {
//Logic to close the sidenav here
}
}
);
}
open(sidenav) {
sidenav.open();
}
close(sidenav) {
sidenav.close();
}
service
import { Injectable } from "@angular/core"
import { Observable, Subject } from "rxjs/Rx";
@Injectable()
export class toggleWidgetService {
private sidenavOpenSubject : Subject<boolean>;
constructor() {
this.sidenavOpenSubject = new Subject<boolean>();
}
toggleSideNav(opening: boolean): void {
this.sidenavOpenSubject.next(opening);
}
onSideNavToggle(): Observable<boolean> {
return this.sidenavOpenSubject;
}
}
Upvotes: 0
Views: 1147
Reputation: 177
In service:
Make observable of your sidenavOpenSubject variable as =>
subject_observable = this.sidenavOpenSubject.asObservable();
In Dashboard Component:
Try to subscribe subject_observable as =>
this.togglewidgetService.subject_observable.subscribe( opening =>
{
//
} )
Upvotes: 0
Reputation: 3451
My best advice is to create a CoreModule that represents a single instance module, and create a pub/sub service to share data across your modules.
CoreModule
import {
ModuleWithProviders, NgModule,
Optional, SkipSelf } from '@angular/core';
//Providers
import { PubSubService } from './pub-sub.service';
/**
* This module handles all the singleton services
*/
@NgModule({
imports: [],
exports: [],
declarations: [],
providers: [PubSubService]
})
export class CoreModule {
constructor( @Optional() @SkipSelf() parentModule: CoreModule) {
if (parentModule) {
throw new Error(
'CoreModule is already loaded. Import it in the AppModule only');
}
}
static forRoot(): ModuleWithProviders {
return {
ngModule: CoreModule,
providers: [PubSubService]
};
}
}
PubSubService
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';
/**
* Publisher/Subscriber Service
*/
@Injectable()
export class PubSubService {
private events: any = {};
constructor() { }
/**
* Subscribes the instance of the assigned event name
* @param eventName
* Event name of the delegate
*/
public On(eventName: PubSubEvents): Observable<any> {
if (typeof this.events[eventName] === 'undefined') {
this.events[eventName] = new Subject<any>();
}
return this.events[eventName].asObservable();
}
/**
* Broadcast data to the specified event channel
* @param eventName
* Event name of the delegate
* @param eventArgs
* Arguments to pass through the connected channel
*/
public Broadcast(eventName: PubSubEvents, eventArgs: any) {
if (!this.events[eventName]) {
return;
}
this.events[eventName].next(eventArgs);
}
}
//Your events
export declare type PubSubEvents = "OnSideNavToggle" | "OnAnyOtherEvent1" | "OnAnyOtherEvent2";
How to use
Make sure CoreModule is only imported once, import it in AppModule
@NgModule({
bootstrap: [ AppComponent ],
imports: [
CoreModule.forRoot(),
]
})
export class AppModule {
}
sidebar component
toggle: boolean = false;
constructor(private pubsub: PubSubService){
}
manageWidgetLocation(){
this.boolean = !this.boolean;
this.pubsub.Broadcast("OnSideNavToggle", this);
}
dashboard component
constructor(private pubsub: PubSubService){
this.pubsub.On("OnSideNavToggle").subscribe((res) =>{
//res -> value of the toggle state
});
}
Upvotes: 1
Reputation: 4208
service
@Injectable()
export class toggleWidgetService {
sidenavOpenSubject: Subject<boolean> = new Subject<boolean>();
}
dashboard
constructor(private service: BlaService) {}
ngOnInit() {
this.service.sidenavOpenSubject.subscribe(
data => console.log(data),
error => console.log(error)
)
}
ngOnDestroy() {
this.service.sidenavOpenSubject.unsubscribe()
}
sidebar
constructor(private service: Service) {}
someFunction() {
this.service.sidenavOpenSubject.next(true);
}
this will work just fine.
Upvotes: 0