Angular2 中的共享服务和 Observable、BehaviourSubject

Posted

技术标签:

【中文标题】Angular2 中的共享服务和 Observable、BehaviourSubject【英文标题】:Shared service and Observable, BehaviourSubject in Angular2 【发布时间】:2018-01-27 20:57:09 【问题描述】:

我有一个共享服务SharedService

@Injectable()
export class SharedService 
  private title = new BehaviorSubject<string>("");
  currentMessage = this.title.asObservable();
  constructor()  
  setData(val: string) 
    this.title.next(val);
  

我有一个组件,我可以在其中获取新数据

export class Fill implements OnInit 
public title;

  constructor(public shared: SharedService) 
  
  ngOnInit() 
this.shared.setData(this.title);

还有组件信息,我想在其中读取新数据 导出类 InfoComponent 实现 OnInit

  constructor(public shared: SharedService)  
    this.title = ''; 
  ngOnInit() 

    console.log('i am title from info ')
    this.shared.currentMessage.subscribe(title => this.title = title)
    console.log(this.shared.currentMessage);
    console.log(this.title);

在 console.log 的两种情况下,我都会得到包含我需要的信息的对象 - 但我无法检索它的值。所以,在我的控制台上看起来像

但是如果尝试类似

console.log(this.shared.currentMessage.source.source.value);

它说属性“源”受保护,只能在“Observable”类及其子类中访问。

this.shared.currentMessage.value
this.title.value

也不行... 我怎样才能检索一个或另一个的数据(值)?

【问题讨论】:

ngOnInit 嵌套在 InfoComponent 内的构造函数中。 是的。 @wostex 正确地提到了它。将 ngOninit 放在构造函数之外。 Get value of Observable or value of BehaviourSubject Angular2的可能重复 【参考方案1】:

ngOnInit 必须在构造函数之外。

正如@micronkys 所指出的那样

当您订阅 observable 时,this.title 的值在下一行中不可用,因为订阅是异步的,因此标题会被更新。当你记录它时。

尝试像这样在模板中使用*ngIf = "title"

<div *ngIf = "title">
  title
</div>

更新

this.shared.currentMessage.subscribe((title) => 
                          this.title = title;
                          console.log(this.title)

请找plunker解决问题希望你现在得到答案

【讨论】:

@AnnaF 也可以查看@这个link 了解更多关于行为主题的信息 @AnnaF 用 plunker 更新了答案以进行行为主题检查【参考方案2】:

更新

我怀疑currentMessage = this.title.asObservable(); 在您的SharedService Injectable 中是无效行。

您可以编写一个方法来公开this.title,通过currentMessage 方法公开,如下所示

@Injectable()
export class SharedService 
  private title = new BehaviorSubject<string>("");
  //below line was wrong.
  //currentMessage = this.title.asObservable();
  currentMessage()
     return this.title.asObservable();
  
  constructor()  
  setData(val: string) 
    this.title.next(val);
  

//Usage
console.log(this.shared.currentMessage().getValue());

是的,你应该先从构造函数中取出ngOnInit。我想你想检索 BehaviourSubject 的初始状态,那么你可以在 Observable 上使用 .getValue() 函数而不订阅流。

console.log(this.shared.currentMessage.getValue());

【讨论】:

在外面,getValue 不起作用 属性 'getValue' 不存在于类型 'Observable'。 我得到一个错误属性 'getValue' 在类型 'Observable' 上不存在。【参考方案3】:

是的。 @wostex 正确地提到了它。将ngOninit 保留在构造函数之外,并且,

this.shared.currentMessage.subscribe(title => 

     this.title = title;
     console.log(this.title)
)

【讨论】:

我以后如何在这个块之外使用它?我需要在其他功能中使用这些数据 对于这种情况,您可以依赖组件中定义的title 变量。您必须使用共享服务并在服务中定义一个标题变量,并在需要时使用它。 在您的情况下,服务已经存在。而titlebehaviourSubject,所以只要你想获取数据,只需subscribetitle behaviourSubject 我得到了数据,对,但是无法从中获取值,这是我的问题

以上是关于Angular2 中的共享服务和 Observable、BehaviourSubject的主要内容,如果未能解决你的问题,请参考以下文章

如何在Angular2中的组件之间共享数据[重复]

使用 Typescript 在 Angular 2 中的组件之间共享行为

Angular2中的共享单选按钮组件

Angular 2 模块/应用程序结构

Angular2从模块导入组件/服务

在网络应用 (Angular2) 和移动应用 (Ionic 2) 之间共享代码