[英]Angular: How to pipe Observable before subscribing in template
免責聲明:這與這個問題密切相關。
目前我有兩個組件, Parent
和Child
。 Parent
將 Observable 傳遞給Child
,后者在模板中訂閱此 Observable 以避免生命周期/內存泄漏問題。 但是我必須在Child
組件中對 Observable 進行pipe
設置一些東西。
父.ts:
public $obs = Observable<any>;
....
loadData() {
this.obs$ = this.myService.getData();
}
父.html:
<child [data$]="obs$"></child>
child.ts:
@Input() data$ : Observable<any>;
ngOnChanges(changes) {
if(changes.data$) {
console.log("changes detected");
this.data$.pipe(tap(data => console.log("tap worked")));
}
}
child.html
<div *ngIf="data$ | async as data;">
{{ data || json }}
</div>
數據存在於模板中,控制台日志顯示已檢測到更改,但從未顯示“點擊工作”,這讓我懷疑我對pipe
的調用可能為時已晚。 在模板“調用”訂閱之前,有什么辦法可以 pipe 嗎?
這個想法是有許多類似於孩子的組件,都在數據 object 上做不同的事情。 我考慮過在Parent
中訂閱服務並將 json 值直接傳遞給所有孩子,但這需要我在所有孩子中寫一個*ngIf
。
我建議您不要直接訂閱data$
。 而是創建另一個您可以閱讀的 Observable。
@Input() data$: Observable<any>;
customData$: Observable<any>;
ngOnChanges(changes) {
if(changes.data$) {
console.log("changes detected");
this.customData$ = this.data$.pipe(tap(data => console.log("tap worked")));
}
}
<div *ngIf="customData$ | async as data;">
{{ data || json }}
</div>
Observables 天生就是懶惰的。 在您訂閱它們之前,它們不會被執行。 要查看“點擊有效”,您需要訂閱它。
this.data$.pipe(tap(data => console.log("tap worked"))).subscribe();
默認情況下, async
會為您訂閱和取消訂閱 observable,還要注意 observable 中的每個訂閱者都會獲得一個新的執行上下文,並且可以覆蓋此行為。
要緩存結果以防訂閱延遲,您可以在服務中使用BehaviourSubject
或ReplaySubject
。
我認為問題出在您的 ngOnChanges 中。 你有條件
if(changes.data$) {
console.log("changes detected");
this.data$.pipe(tap(data => console.log("tap worked")));
}
這將檢查 data$ 的引用是否會更改,但不會檢查 data$ 是否發出您真正想要的新值。 因此,您的點擊沒有執行。
相反,你可以
public data$: Observable<any>;
@Input() set data(data$: Observable<any>) {
this.data$ = data$.pipe(tap(x => console.log("tap worked")));
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.