【问题标题】:Data sharing between components in Angular 6Angular 6 中组件之间的数据共享
【发布时间】:2019-04-28 20:16:34
【问题描述】:

我已经创建了 2 个组件和一个服务,如下所示,

组件交互.service.ts

@Injectable()
export class ComponentInteractionService {

  public dataSubject = new BehaviorSubject<string>("Test");

  getTestData(): Observable<any> {
    return this.dataSubject.asObservable();
  }

  pustTestData(dataToPush: string): void {
    this.dataSubject.next(dataToPush);
  }
}

first.component.ts

export class FirstComponent {

  constructor(private componentInteractionService: ComponentInteractionService) { 
    componentInteractionService.getTestData().subscribe(data=> {
      console.log("Received at 1 -- " + data);
    });
  }

  sendTestData(): void {
    this.componentInteractionService.pustTestData("sending data from 1");
  }

}

second.component.ts

export class SecondComponent {

  constructor(private componentInteractionService: ComponentInteractionService) { 
    componentInteractionService.getTestData().subscribe(data=> {
      console.log("Received at 2 -- " + data);
    });
  }
}

我目前面临的问题是

在页面加载时,两个组件订阅者都被触发,但是当我使用 FirstComponent 中的 sendTestData() 方法推送数据时,只有 FirstComponent 正在被触发。 SecondComponent 中的订阅者没有被触发。 我应该怎么做才能让两个订阅者在使用 sendTestData() 方法推送数据时被触发?

我的控制台日志如下..

1 点收到——测试

2 点收到 -- 测试

在 1 接收——从 1 发送数据

预期输出..

1 点收到——测试

2 点收到 -- 测试

在 1 接收——从 1 发送数据

在 2 接收——从 1 发送数据

【问题讨论】:

  • 尝试调用ngOnInit() 而不是constrcutor()
  • 我试过这个,但仍然面临同样的问题。
  • 为什么要创建单独的函数?您可以直接使用dataSubject,像这样:this.componentInteractionService.dataSubject.subscribe(x=&gt; { console.log(x)}); 并在您的ngOnInit 中调用它。
  • 您能创建一个 stackblitz 示例来重现您的问题吗?
  • 注意:推送数据方法在第二个组件中是不可见的。您已经在 dataSubject 上创建了 behaviorSubject,因此您将收到数据

标签: angular observable angular6 behaviorsubject


【解决方案1】:

这是因为您在 AppComponentOne 和 AppComponentTwo 中提供了两次相同的服务,所以它们都有相同服务的不同实例。

两个组件的空providers数组并在app.module.ts内提供服务

@Component({
  selector: 'app-distinct-first-component',
  template: '<button (click)="sendTestData()">Click to send Data</button>',
  providers: [ComponentService] // <= remove this line from both components
})

app.module.ts

@NgModule({
  imports:      [ BrowserModule, FormsModule ],
  declarations: [ AppComponent, HelloComponent, 
  FirstComponent, SecondComponent
  ],
  bootstrap:    [ AppComponent ],
  providers: [ComponentService] // <= provide it here
})
export class AppModule { }

【讨论】:

  • 谢谢 :) 当我在父组件中导入服务时它起作用了。
【解决方案2】:

对我来说工作得很好。检查这个demo控制台

这里是相关代码

common.service.ts

@Injectable()
export class CommonService {

public dataSubject$: Subject<string> = new BehaviorSubject<string>("Test");

getData(): Observable<any> {
    return this.dataSubject$.asObservable();
}

setData(dataToPush: string): void{
    this.dataSubject$.next(dataToPush);
 }
}

first.component.ts

@Component({
    selector: 'app-first',
    template: `First Component data`,
})

export class FirstComponent implements OnInit {

constructor(
      private commonService: CommonService,
    ) { 

    }

    ngOnInit(){
      this.sendCommonData();
      this.getCommonData();
    }

 getCommonData () {
   this.commonService.getData().subscribe(data=> {
        console.log("Received at 1 -- " + data);
    })
 }

sendCommonData() {
    this.commonService.setData("sending data from first");
}

}

second.component.ts

import { Component, OnInit } from '@angular/core';

import { CommonService } from './common.service';

@Component({
    selector: 'app-second',
    template: `Second Component data `,
})

export class SecondComponent implements OnInit {

constructor(
      private commonService: CommonService,
    ) { 

    }

    ngOnInit(){
      this.getCommonData();
    }

 getCommonData () {
   this.commonService.getData().subscribe(data=> {
        console.log("Received at 2 -- " + data);
    })
 }


}

【讨论】:

【解决方案3】:
 sendTestData(): void {
  this.componentInteractionService.pustTestData("sending data from 1");
  // must call the observable once after adding new data
  this.commonService.getData();
 }

你必须在给行为主体设置新数据后调用observable。

【讨论】:

  • 试过了。这没有用。由于我已经在构造函数中调用了它,我相信它已经被注册了。
猜你喜欢
  • 2019-08-07
  • 2019-08-04
  • 2021-05-03
  • 2018-10-12
  • 1970-01-01
  • 2023-03-10
  • 2020-03-14
  • 2018-09-27
相关资源
最近更新 更多