Обмен данными между компонентами в Angular

проблема с совместным использованием данных компонентов. У меня есть 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;
                                          }

              }

В чем проблема?

bugs 02.05.2018 10:01

возможный дубликат stackoverflow.com/questions/43585998/…

Luca Taccagni 02.05.2018 10:09

И компоненты, и сервис находятся в отдельном модуле?

John Velasquez 02.05.2018 11:41

@ Джон Веласкес да

pankaj malik 02.05.2018 11:42

Проверьте подход создания subject в stackblitz.com/edit/…. Надеюсь, это поможет stackoverflow.com/questions/49898893/…. Вы можете создать модуль common, тема которого является subscribed другими компонентами модуля.

Shashank Vivek 02.05.2018 12:37
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
0
5
621
3

Ответы 3

услуга

@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);
}

это будет работать нормально.

спасибо за ответ, но у меня это не работает

pankaj malik 02.05.2018 10:37

Мой лучший совет - создать 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 =>
  {
 // 
  } )

Вы можете объяснить сервисную часть. не понимаю тебя.

pankaj malik 02.05.2018 14:37

Здесь мы объявляем наблюдаемый, так что когда любое изменение значения sidenavOpenSubject встречается, оно может быть прослушано в компоненте панели инструментов.

shubham agarwal 02.05.2018 15:54

Другие вопросы по теме