Re: [問題] Angular的service在路由間觸發的問題
※ 引述《heavenbetula (綠草)》之銘言:
: 大家好~小弟是Angular剛接觸沒多久的新手
: 最近在使用Service在路由間跳轉時遇到一些問題
: https://stackblitz.com/edit/angular-w3njbx
: ↑上面的程式,我在child1 component中訂閱了service裡的Subject物件,
: 而在child2 component的按鈕按下後,才會接收到觸發了,而去做後續行為
: 這個例子中,我預期的就是按鈕每按一次,我就console.log一次,
: 但是我發現,在路由跳轉的過程中,只要child2 component進入一次
: 就會連同上次的紀錄都留著,也就是說:
: 第一次進入child2 component按下按鈕一次,console.log一次(正常)
: 先按連結離開child2 component
: 第二次再進入child2 compoent按下按鈕一次,console.log直接跳出兩次結果
: 先按連結離開child2 component
: 第三次再進入child2 component按下按鈕一次,console.log直接跳出三次結果
: 請問為什麼會這樣呢?
你在Child1Component中用constructor injection注入service
因為Angular的DI機制,沒特別設定Injector的話service會從component開始往上找
然後你的FooteractionService只有由AppModule做Provider
所以service的instance是singleton
每次切換路由時會建立/消滅Component
每次切換到Child1的路由時都會產生一個Child1的instance
並且每次注入的都是同一個service
訂閱的也都是同一個service裡的subject
訂閱寫在constructor裡每次Child1產生一次就訂閱一次
呼叫service.action()的時候因為之前的訂閱沒有被取消掉,
自然會重複觸發subscribe()裡面的callback
目前普遍建議的做法大概是這樣
在Child1中給一個$destroy的property = new Subject<void>();
Class implements OnDestroy
在生命週期方法內做$destroy.next()和$destroy.unsubscribe()
然後在訂閱service內subject的時候不要直接訂閱
用subject.pipe(takeUntil(this.$destroy)).subscribe()
這樣Child1因為路由變更消滅後
訂閱的subject發送時就不會觸發該次的subscribe()裡面的callback
如果上面的原理看不懂的話就抄最後的程式碼就好了
但是如果要繼續玩Angular甚至拿它來做大專案
還是要了解一下他的routing跟DI 還有RxJS的原理以及operators
這樣過程會比較愉快一點
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 123.240.48.162
※ 文章網址: https://www.ptt.cc/bbs/Web_Design/M.1545843781.A.ED8.html
※ 編輯: LoveMoon (123.240.48.162), 12/27/2018 01:14:14
推
12/27 21:19,
5年前
, 1F
12/27 21:19, 1F
→
12/27 21:21,
5年前
, 2F
12/27 21:21, 2F
→
12/27 21:23,
5年前
, 3F
12/27 21:23, 3F
→
12/27 21:24,
5年前
, 4F
12/27 21:24, 4F
不知道你的看不懂是指哪邊
如果是routing跟component的關係,你需要了解routing
如果是component跟construction injection的關係,你需要了解DI
如果是重複訂閱的問題,你需要了解observer pattern和RxJS
不了解Angular和RxJS我覺得沒什麼
但是你需要能夠從關鍵字去延伸閱讀相關的知識和文件
下面文章
第一篇是takeUntil vs. Subscription.unsubscribe
第二篇是使用takeUntil時需要注意的地方
請你自己閱讀
https://medium.com/@benlesh/rxjs-dont-unsubscribe-6753ed4fda87
https://blog.angularindepth.com/rxjs-avoiding-takeuntil-leaks-fb5182d047ef
※ 編輯: LoveMoon (123.240.48.162), 12/27/2018 22:51:11
→
12/27 22:55,
5年前
, 5F
12/27 22:55, 5F
→
12/27 22:55,
5年前
, 6F
12/27 22:55, 6F
→
12/27 22:58,
5年前
, 7F
12/27 22:58, 7F
→
12/27 22:59,
5年前
, 8F
12/27 22:59, 8F
推
12/28 12:59,
5年前
, 9F
12/28 12:59, 9F
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 2 之 2 篇):