【问题标题】:Sharing data between components in Angular在 Angular 中的组件之间共享数据
【发布时间】:2018-10-12 06:34:01
【问题描述】:

组件数据共享出现问题。我有 2 个组件,它们没有父子关系。在我的侧边栏组件中,我有一个复选框,通过单击此复选框,我想在我的仪表板组件中执行一些操作。

侧边栏组件

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

              }

【问题讨论】:

标签: angular angular5 angular2-services


【解决方案1】:

我最好的建议是创建一个代表单个实例模块的 CoreModule,并创建一个 pub/sub 服务来在您的模块之间共享数据。

核心模块

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】:

    服务

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

    这样就可以了。

    【讨论】:

    • 感谢您的回复,但这对我不起作用
    【解决方案3】:

    在役:

     Make observable of your sidenavOpenSubject variable as =>
    
        subject_observable = this.sidenavOpenSubject.asObservable();
    

    在仪表板组件中:

    Try to subscribe subject_observable as =>    
    
    this.togglewidgetService.subject_observable.subscribe(   opening =>
      {
     // 
      } )
    

    【讨论】:

    • 你能解释一下服务部分吗?没有得到你。
    • 这里我们声明了observable,这样当sidenavOpenSubject的值发生变化时,可以在dashboard组件中监听。
    猜你喜欢
    • 2019-08-04
    • 2023-03-10
    • 2020-03-14
    • 2018-09-27
    • 2019-04-28
    • 2018-02-17
    • 2021-01-04
    • 2019-01-22
    相关资源
    最近更新 更多