组件未订阅Observable

时间:2018-11-29 19:10:01

标签: angular rxjs

我有一个非常基本的设置。组件A呈现组件B。

组件A暴露了Subject,并在其模板中将主题(使用异步管道)传递给组件B的属性之一:

@Component({
  template: "
    <div><app-comp-b [input]='s | async'></app-comp-b></div>
  "
})
class CompA {
  s: BehaviorSubject<string> = new BehaviorSubject<string>('');
  change(newS: string) { this.s.next(newS); }
}  

class CompB {
  @Input() input: string;
}

由于某种原因,B仅获得s的初始值。随后对change的调用(在s中创建一个新值)对B无效。也就是说,input的值不变(例如,如果我将其渲染为B的模板)。

如果我手动订阅s,例如s.subscribe(ss => console.log(ss));我可以看到输入的值在控制台中打印出来。

更重要的是,如果我使用pipetap来打印值,则在我手动订阅之前什么也不会发生。这向我暗示了Comp B没有订阅s

我在做什么错? (我使用的是角4.4.7)

1 个答案:

答案 0 :(得分:1)

感谢@SiddAjmera示例,我发现了问题。

在我的代码中,change()函数不是由按钮调用的,而是由另一个组件触发的事件触发的。当我使用按钮时,它开始工作!

因此,我向detectChanges添加了一个呼叫,该呼叫现在也可以在该事件中使用。

我是Angular的新手,但如果我理解正确,Angular不会检测到更改,因为对Subject s的引用没有更改。而是使用新值更新它。因此,我们必须强制检测更改。

要添加detectChanges,我将变化检测器注入了comp A的c'tor中,并称为检测change中的变化:

class CompA {
  constructor(private cd: ChangeDetectorRef) {}

  s: BehaviorSubject<string> = new BehaviorSubject<string>('');

  change(newS: string) { 
    this.s.next(newS);
    this.cd.detectChanges();
  }
}