проблема с совместным использованием данных компонентов. У меня есть 2 компонента, у них нет родительских и дочерних отношений. в моем компоненте боковой панели у меня есть флажок, щелкнув этот флажок, я хочу выполнить какое-то действие в моем компоненте панели инструментов.
компонент боковой панели
manageWidgetLocation(){
this.togglewidgetService.toggleSideNav(true);
}
компонент приборной панели
ngOnInit(): void {
this.togglewidgetService.onSideNavToggle()
.subscribe(
(opening) => {
debugger;
if (opening) {
console.info(">>>>>>>here");
} else {
//Logic to close the sidenav here
}
}
);
}
open(sidenav) {
sidenav.open();
}
close(sidenav) {
sidenav.close();
}
услуга
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;
}
}
возможный дубликат stackoverflow.com/questions/43585998/…
И компоненты, и сервис находятся в отдельном модуле?
@ Джон Веласкес да
Проверьте подход создания subject
в stackblitz.com/edit/…. Надеюсь, это поможет stackoverflow.com/questions/49898893/…. Вы можете создать модуль common
, тема которого является subscribed
другими компонентами модуля.
услуга
@Injectable()
export class toggleWidgetService {
sidenavOpenSubject: Subject<boolean> = new Subject<boolean>();
}
приборная панель
constructor(private service: BlaService) {}
ngOnInit() {
this.service.sidenavOpenSubject.subscribe(
data => console.info(data),
error => console.info(error)
)
}
ngOnDestroy() {
this.service.sidenavOpenSubject.unsubscribe()
}
боковая панель
constructor(private service: Service) {}
someFunction() {
this.service.sidenavOpenSubject.next(true);
}
это будет работать нормально.
спасибо за ответ, но у меня это не работает
Мой лучший совет - создать CoreModule, который представляет модуль с одним экземпляром, и создать службу pub / sub для обмена данными между вашими модулями.
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";
Как использовать
Make sure CoreModule is only imported once, import it in AppModule
@NgModule({
bootstrap: [ AppComponent ],
imports: [
CoreModule.forRoot(),
]
})
export class AppModule {
}
компонент боковой панели
toggle: boolean = false;
constructor(private pubsub: PubSubService){
}
manageWidgetLocation(){
this.boolean = !this.boolean;
this.pubsub.Broadcast("OnSideNavToggle", this);
}
компонент приборной панели
constructor(private pubsub: PubSubService){
this.pubsub.On("OnSideNavToggle").subscribe((res) =>{
//res -> value of the toggle state
});
}
В сервисе:
Make observable of your sidenavOpenSubject variable as =>
subject_observable = this.sidenavOpenSubject.asObservable();
В компоненте приборной панели:
Try to subscribe subject_observable as =>
this.togglewidgetService.subject_observable.subscribe( opening =>
{
//
} )
Вы можете объяснить сервисную часть. не понимаю тебя.
Здесь мы объявляем наблюдаемый, так что когда любое изменение значения sidenavOpenSubject встречается, оно может быть прослушано в компоненте панели инструментов.
В чем проблема?