在Angular中共享组件之间的数据

时间:2018-05-02 08:01:05

标签: angular angular5 angular2-services

在组件数据共享中遇到问题。我有两个组成部分,他们没有父母的孩子关系。在我的侧边栏组件中我有一个复选框,通过单击此复选框,我想在我的仪表板组件中执行一些操作。

侧栏组件

  manageWidgetLocation(){
  this.togglewidgetService.toggleSideNav(true);
  }

信息中心组件

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

服务

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

              }

3 个答案:

答案 0 :(得分:0)

<强>服务

@Injectable()
export class toggleWidgetService {
  sidenavOpenSubject: Subject<boolean> = new Subject<boolean>();
}

<强>仪表板

constructor(private service: BlaService) {}

ngOnInit() {
  this.service.sidenavOpenSubject.subscribe(
    data => console.log(data),
    error => console.log(error)
  )
}

ngOnDestroy() {
  this.service.sidenavOpenSubject.unsubscribe()
}

<强>边栏

constructor(private service: Service) {}

someFunction() {
  this.service.sidenavOpenSubject.next(true);
}

这样可以正常工作。

答案 1 :(得分:0)

我最好的建议是创建一个代表单个实例模块的 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";

如何使用

  

确保仅导入CoreModule一次,将其导入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
  });
}

答案 2 :(得分:0)

在服务中:

newtype

在仪表板组件中:

 Make observable of your sidenavOpenSubject variable as =>

    subject_observable = this.sidenavOpenSubject.asObservable();