Re: [問題] Angular的service在路由間觸發的問題

看板Web_Design作者 (我不是魔獸三國作者.....)時間5年前 (2018/12/27 01:03), 5年前編輯推噓2(207)
留言9則, 2人參與, 5年前最新討論串2/2 (看更多)
※ 引述《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
不過也有爬文說設置一個Subscription型別的屬性
12/27 21:21, 2F

12/27 21:23, 5年前 , 3F
讓這個屬性=subscribe的callback
12/27 21:23, 3F

12/27 21:24, 5年前 , 4F
我直接在原文打好了比較好理解XD
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
如果有時間的話我會在blog寫observer patter的介紹
12/27 22:58, 7F

12/27 22:59, 5年前 , 8F
真的有寫出來再把連結貼給你
12/27 22:59, 8F

12/28 12:59, 5年前 , 9F
謝謝其實我是takeUntil那邊沒用過不知道
12/28 12:59, 9F
文章代碼(AID): #1S8xH5xO (Web_Design)
文章代碼(AID): #1S8xH5xO (Web_Design)