簡體   English   中英

如何在ui-router中保留瀏覽器上的可選狀態參數?

[英]How to persist optional state parameter on browser back in ui-router?

我有一個父狀態,里面有兩個孩子的狀態,我將根據URL顯示一個狀態。

在這兩個states一個是參數,如param1param2 ,我在狀態定義中使用了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,我已經顯示了兩個標簽AccountSurvey

  1. 單擊Survey選項卡,然后在textarea添加一些顯示的數據。
  2. 單擊轉到帳戶 ,通過在錨點上執行ui-sref="tabs.account({param1: thing1, param2: thing2})"將這些textarea值傳遞到另一個帳戶選項卡

  3. 現在,您將在html上看到已從$stateParams分配到范圍的param1param2

  4. 現在再次點擊Survey選項卡,您將登陸調查頁面。
  5. 只需單擊瀏覽器,您就會注意到param值未變為null

問題Plunkr

我相信你有我想問的問題,為什么可選參數值沒有存儲? 因為他們是國家的一部分。

我知道我可以通過以下兩種解決方案來解決這個問題。

  • 通過創建一個將在兩個視圖之間共享數據的服務。
  • 通過在狀態URL中添加參數。 url: '/account/:param1/:param2', (但我不喜歡這個)

我已經嘗試過angular-ui-routers sticky states但這似乎對我沒用。 有什么更好的方法呢?

有什么方法可以使我的用例工作,任何想法都會很感激。

Github 問題鏈接在這里

我會將params定義移動到父狀態,以便在兩個子狀態之間共享可選的狀態參數。

子狀態將從父級繼承$stateParams ,因此不需要真正的“解決方法”。

只需按照常規方式在您的子控制器中注入$stateParams ,您就可以完全訪問被傳遞的參數。 如果您不想在特定的子狀態下使用params,只需避免注入它們。

這適用於;

  • 返回鍵
  • 前進按鈕
  • ui-sref (沒有參數(將保持原樣))
  • ui-sref (用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的州樹狀態下旅行時想要清除參數,則必須手動執行此操作。

這將是我通過使用此解決方案可以看到的唯一真實警告。

我知道在你出席的情況下手動清算可能並不理想,但你沒有采取積極的立場反對它,因此我認為這個建議是有價值的。

更新的plunker

一種解決方法是在進入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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM