2017-08-10 44 views
1

這是一個與Angular 4相關的體系結構問題,以及如何以角度加載子組件的方式來初始化數據。如何安全地重複加載/初始化相同的子組件

場景: 我有一個帶有數據表的父組件,當表中的任何一行被點擊時,它會打開3個子組件之一(在側欄視圖中),具體取決於是否要向表中添加一個新項,編輯選定的行或查看關於它的詳細信息(基本CRUD功能)。 IOTW,用戶可以重複調用相同的3個組件,因爲它們處理父組件中的數據表。

通過角度設計,子組件僅在第一次使用組件時運行OnInit生命週期事件。例如,如果我編輯第1行,'edit'子組件運行onInit鉤子,但是,如果我隨後編輯第2行,編輯組件中的onInit將不會運行,因爲該組件已經根據角度加載。

爲了能夠初始化每一次用戶想要做一些像編輯一個新選擇行(母公司數據表的操作)的子組件的數據,我使用onChanges生命週期鉤子組件。

問題: 我懷疑這種通過onChanges初始化數據的方法是一種反模式,因爲onChanges在子組件中反覆運行,迫使我警惕哪些初始化代碼可以放在那裏。

問: 有沒有更好的方式來加載子組件,讓我能夠可靠地對它們進行初始化只有一次每個每次由父組件觸發時間和?

謝謝

S.阿羅拉

+0

不知道你的子組件是如何初始化的(動態的?),取決於它是如何完成的,你可以使用'NgZone' – 12seconds

+0

每個子組件都有一個* ngIf來決定它是否應該顯示一個'selectedRow'輸入。當用戶在父組件的數據表中的特定行上觸發'編輯'按鈕時,編輯組件運行onInit(第一次用戶單擊編輯)和ngOnChanges(任何時候selectedRow的輸入變量更改,或者我猜其他任何輸入/輸出變量在子組件上發生變化)。 – sarora

+0

我正在研究你對ngZone的建議,以及其他一些選項,如強制onInit重新運行(詳見https://stackoverflow.com/questions/36513241/reinit-on-input-change)。選擇解決方案的一個考慮因素是我目前正在依靠變化檢測將selectedRow輸入變量傳遞給子組件,並且該子組件的初始化代碼重新運行之前總是需要傳遞該輸入。只要一個強制的方法尊重ngOnChange循環首先運行,我想它可以工作。會嘗試。 – sarora

回答

0

我試圖迫使OnInit的重新運行的一種方式的選擇安全地初始化時需要但不幸的是它運行在接受輸入變量之前,所以它沒有它需要初始化的東西。

退一步說,我想我在這裏試圖解決錯誤的問題..我相信我需要依靠角度的標準方式通過輸入參數傳遞數據並利用ngOnChanges來重新初始化基於子組件在新的輸入變量上。

我遇到真正的缺陷是什麼,我提到我的時候說:「onChanges重複運行的子組件」 ..它是什麼扔我送行,並與變通辦法,這裏詳細:https://github.com/angular/angular/issues/7782

因此,對組件加載一次性序列是:1)運行onChanges(輸入變量爲空)2)運行onInit 3)運行onChanges(輸入變量最新)。

隨後,當輸入變量發生變化時,序列就會簡單地運行onChanges,因此如果您可以忽略步驟#1中的第一個空參數,那麼就不會出現biggie。

但是,不僅onChanges在加載子組件時運行兩次,而且它重複描述的1-2-3序列,如果您替換子組件以顯示,就像我的場景中用戶可以在加載編輯/查看他們在數據表中選擇的給定數據行的子組件。

要啓動,在步驟#1我注意到angular會通過一個陳舊的輸入參數onChanges運行時,在傳遞第3步的最新輸入參數之前。

如果你的子組件具有冪等初始化代碼,你可能永遠不會注意到所有這些,但在我的情況下,步驟#1和#3快速連續觸發並觸發不是冪等的Observable訂閱... !)。除非/直到設計角度的缺陷得到解決,否則我想這個缺陷仍然存在。希望這有助於...