我有一个非常基本的设置。组件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));
我可以看到输入的值在控制台中打印出来。
更重要的是,如果我使用pipe
和tap
来打印值,则在我手动订阅之前什么也不会发生。这向我暗示了Comp B没有订阅s
。
我在做什么错? (我使用的是角4.4.7)
答案 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();
}
}