web-dev-qa-db-ja.com

ブラウザのオプションの状態パラメータをui-routerに永続化する方法は?

URLに基づいて1つの状態を表示するために、2つの子の状態を持つ1つの親状態があります。

これらの2つのstatesのうち、1つは_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を見て、2つのタブAccountSurvey

  1. [調査]タブをクリックして、表示されているtextareaにデータを追加します。
  2. Go to Accountをクリックして、これらのtextarea値を他のAccountアンカーでui-sref="tabs.account({param1: thing1, param2: thing2})"を実行してタブ

  3. これで、_param1_からスコープに割り当てられたHTMLの_param2_および_$stateParams_値が表示されます。

  4. もう一度Surveyタブをクリックすると、調査ページが表示されます。
  5. ブラウザーをクリックして戻ると、paramの値がnullになっていないことがわかります。

Problem Plunkr

オプションのパラメーター値が保存されていないのはなぜですか?彼らが国家の一部であったので。

次の2つの解決策でこの問題を解決できることを知っています。

  • 2つのビュー間でデータを共有する1つのサービスを作成する。
  • 状態URL内にパラメーターを追加する。 _url: '/account/:param1/:param2',_のように(しかし、私はこれを好みません)

Angular-ui-routers _sticky states_ をすでに試しましたが、それは私にはうまくいかないようです。これのより良い方法は何ですか?

私のユースケースを機能させる方法はありますか?.

Github Issue Link Here

31
Pankaj Parkar

2つの子状態間でオプションの状態パラメーターを共有するために、params定義を親状態に移動します。

子の状態は親から$stateParamsを継承するため、実際の「回避策」は必要ありません。

通常どおり、子コントローラーに$stateParamsを挿入するだけで、渡されるパラメーターに完全にアクセスできます。特定の子の状態でparamsを利用したくない場合は、単にそれらを注入しないようにします。

これは動作します。

  • 戻るボタン
  • 進むボタン
  • ui-sref(paramsなし(現状のまま))
  • 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の状態ツリー内を移動中にパラメータをclearしたい場合は、そうする必要があります手動で。

これはonly実際の警告ですが、このソリューションを使用することで確認できます。

あなたが提示する場合、手動でのクリアは望ましくないかもしれませんが、提案にはメリットがあると感じているので、積極的に反対していません。

更新されたプランカー

20
Kasper Lewau

1つの回避策ソリューションは、状態パラメーターをキャッシュし、tabs.account状態に入るときに条件付きでそれらをロードすることです。 UIルーターの状態の構成では、これらのタイプの「状態に入るときに何かを行う」状況に対して実際にonEnterコールバックを提供できます。

ここでは、キャッシュとして localStorage を使用し、Plunker here を使用する基本的なロジックを示します。

  • 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');
      }
    }],
    ...
  }

1つ警告は、パラメーターが無期限に保持されることです(たとえば、更新とセッション間で)。これを回避するには、app.runのように、アプリケーションの読み込み時にキャッシュをクリアします。

最後の注意点は、Plunkerでローカルストレージに直接アクセスしていることです(Angular $windowサービスを介して)。AngularJSモジュールを使用したい場合があります-私は angular-local-storage 運用中です。

7
Christian Yang

あなたが達成したいことは、あなたが提供した2つのソリューションのいずれかを使用しないと不可能だと思います。

ブラウザの戻るボタンは、URLの履歴を保持しているだけです。彼はui-routerの内部状態についての手がかりがなく、URLを強制的に変更するだけです。

URLを強制的に変更すると、内部ui-routerマシンがトリガーされますが、残念ながらui-routerは、誰かが手動でURLを変更した場合と同じようにURLの変更を確認します。

Ui-routerは、URLが指すルートへの新しいルート変更を起動します。つまり、彼はあなたが「戻る」ことを望んでいたことを知らず、パラメーターなしで状態を新しいものに変更するだけです。

概要

戻るボタンをクリックすると、前の状態に戻る代わりに、URLに従ってnew状態への状態変更が発生します。

これが、URLにパラメータを追加することで問題が解決する理由です。 URLは差別的であるため、最終的には目的の状態に到達します。

お役に立てば幸いです。

2
Okazari

私にはこれは X Y問題 のように聞こえます。問題がこの表面の外にあるのに対し、状態パラメーターを永続化する方法がいくつか提案されています。

質問の定義により、州とは無関係に保たれるべきデータがあります。ですから、それは州に対して相対的な一種のグローバルです。したがって、それを保持するサービスがあり、両方の状態のコントローラーが必要に応じてそれを維持します。状態パラメーターで1つの状態のスコープ外のデータを渡さないでください。

スティッキー状態は、別の状態がアクティブである間、DOMと$scopeを維持できるため、このアプローチに簡単に適合します。ただし、状態が再アクティブ化されるときの状態パラメータとは関係ありません。

0
Kirill Slatin