[英]How to persist optional state parameter on browser back in ui-router?
我有一個父狀態,里面有兩個孩子的狀態,我將根據URL
顯示一個狀態。
在這兩個states
一個是參數,如param1
和param2
,我在狀態定義中使用了ui-router的params
選項。
州
$stateProvider.state('tabs.account', {
url: '/account',
views: {
'content@tabs': {
templateUrl: 'account.html',
controller: function($scope, $stateParams) {
//This params are internally used to make ajax and show some data.
$scope.param1 = $stateParams.param1;
$scope.param2 = $stateParams.param2;
},
}
},
params: {
param1: { value: null }, //this are optional param
param2: { value: null } //because they are not used in url
}
});
如果你查看我的路線,params選項並沒有在URL
真正引入,這就是為什么我當時認為是可選的。
看看plunkr,我已經顯示了兩個標簽Account & Survey ,
textarea
添加一些顯示的數據。 單擊轉到帳戶 ,通過在錨點上執行ui-sref="tabs.account({param1: thing1, param2: thing2})"
將這些textarea
值傳遞到另一個帳戶選項卡
現在,您將在html上看到已從$stateParams
分配到范圍的param1
和param2
值
param
值未變為null
。 我相信你有我想問的問題,為什么可選參數值沒有存儲? 因為他們是國家的一部分。
我知道我可以通過以下兩種解決方案來解決這個問題。
url: '/account/:param1/:param2',
(但我不喜歡這個) 我已經嘗試過angular-ui-routers sticky states
但這似乎對我沒用。 有什么更好的方法呢?
有什么方法可以使我的用例工作,任何想法都會很感激。
Github 問題鏈接在這里
我會將params
定義移動到父狀態,以便在兩個子狀態之間共享可選的狀態參數。
子狀態將從父級繼承$stateParams
,因此不需要真正的“解決方法”。
只需按照常規方式在您的子控制器中注入$stateParams
,您就可以完全訪問被傳遞的參數。 如果您不想在特定的子狀態下使用params,只需避免注入它們。
這適用於;
$stateProvider
.state('parent', {
params: { p1: null, p2: null }
})
.state('parent.childOne', {
url: '/one',
controller: function ($stateParams) {
console.log($stateParams); // { p1: null, p2: null }
}
})
.state('parent.childTwo', {
url: '/two',
controller: function ($stateParams) {
console.log($stateParams); // { p1: null, p2: null }
}
})
如果您在parent
的州樹狀態下旅行時想要清除參數,則必須手動執行此操作。
這將是我通過使用此解決方案可以看到的唯一真實警告。
我知道在你出席的情況下手動清算可能並不理想,但你沒有采取積極的立場反對它,因此我認為這個建議是有價值的。
一種解決方法是在進入tabs.account
狀態時緩存狀態參數並有條件地加載它們。 UI路由器狀態配置實際上允許您為這些類型的“在進入狀態時執行某些操作”情況提供onEnter
回調。
這是使用localStorage作為緩存的基本邏輯,在這里使用Plunker:
tabs.account
狀態時,請檢查您的狀態參數
$stateParams
這是一個示例代碼片段供參考(取自Plunker):
$stateProvider.state('tabs.account', { ... onEnter: ['$stateParams', '$window', function($stateParams, $window) { if($stateParams.param1) { $window.localStorage.setItem('tabs.account.param1', $stateParams.param1); } else { $stateParams.param1 = $window.localStorage.getItem('tabs.account.param1'); } if($stateParams.param2) { $window.localStorage.setItem('tabs.account.param2', $stateParams.param2); } else { $stateParams.param2 = $window.localStorage.getItem('tabs.account.param2'); } }], ... }
需要注意的是,你的參數將無限期地持續存在(例如跨越刷新和會話)。 要解決這個問題,您可以像app.run
一樣清除應用程序負載上的緩存。
最后一點是在Plunker中,我直接訪問本地存儲(通過Angular $window
服務)。 您可能想要使用一些AngularJS模塊 - 我在生產中使用了角度局部存儲 。
我相信如果不使用您提供的兩種解決方案之一,您無法實現的目標。
瀏覽器后退按鈕只保留URL歷史記錄。 他對ui-router內部狀態一無所知,只會強制更改URL。
強制URL更改將觸發內部ui-router機器,但不幸的是ui-router將看到URL更改,就像有人會手動更改URL一樣。
Ui-router將觸發新路由更改到URL指向的路由。 這意味着他不知道你想要“退回”並且只會將狀態改為沒有任何參數的新狀態。
摘要
單擊后退按鈕將根據URL將狀態更改觸發到新狀態,而不是返回到先前狀態。
這就是為什么在URL中添加params解決問題的原因。 由於URL具有歧視性,因此您最終會登陸您想要的狀態。
希望它有所幫助。
對我來說,這聽起來像XY問題 。 有建議的方法使狀態參數持久,而問題是在這個表面之外。
根據問題的定義,應該保持獨立於國家的數據。 所以這是一種全球性的相對於國家。 因此應該有一個服務來保持它和兩個州的控制器按要求維護它。 只是不要在狀態參數中傳遞超出一個狀態范圍的數據。
粘性狀態很容易適合這種方法,因為它允許在另一個狀態處於活動狀態時保留DOM和$scope
。 但是當國家重新啟動時,它與國家參數無關。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.