`ui-router` $ stateParamsと$ state.params


116

を使用するとui-router、どちらか$stateまたは$stateParamsコントローラに挿入して、URLのパラメータにアクセスできます。ただし、を介し$stateParamsてパラメーターにアクセスすると、それにアクセスするコントローラーによって管理されている状態とその親の状態に属するパラメーターのみが公開され、$state.params子の状態にあるものも含めてすべてのパラメーターが公開されます。

次のコードを考えると、URLを直接ロードするとhttp://path/1/paramA/paramB、コントローラーがロードされたときに次のようになります。

$stateProvider.state('a', {
     url: 'path/:id/:anotherParam/',
     controller: 'ACtrl',
  });

$stateProvider.state('a.b', {
     url: '/:yetAnotherParam',
     controller: 'ABCtrl',
  });

module.controller('ACtrl', function($stateParams, $state) {
   $state.params; // has id, anotherParam, and yetAnotherParam
   $stateParams;  // has id and anotherParam
}

module.controller('ABCtrl', function($stateParams, $state) {
   $state.params; // has id, anotherParam, and yetAnotherParam
   $stateParams;  // has id, anotherParam, and yetAnotherParam
}

問題は、なぜ違いがあるのか​​、です。また、いつどのような理由で使用する必要があるか、またはどちらも使用しないようにするためのベストプラクティスガイドラインはありますか?


このように見事に説明された質問-私が尋ねようとしていたことを教えてくれてありがとう!
Peter Nixey 2017

回答:


65

ドキュメントはあなたの発見をここで繰り返します:https : //github.com/angular-ui/ui-router/wiki/URL-Routing#stateparams-service

私の記憶が役立つ場合、$stateParamsオリジナルよりも後に導入さ$state.paramsれ、継続的な書き込みを避けるための単純なヘルパーインジェクターのよう$state.paramsです。

ベストプラクティスのガイドラインはないと思いますが、状況がわかります。URLに受け取ったパラメータにアクセスしたいだけの場合は、$stateParams。状態自体についてより複雑な情報を知りたい場合は、を使用してください$state


1
が設定されているかどうかを確認したいので、私はで使用$state.paramsしていることに気付きました。そうでなければ、私は何かをすることができます。それ自体の質問を正当化できるので、私はその何かの詳細には触れません。しかし、私は、子の状態によって導入され、現在の状態では認識されないパラメータをを介してチェックすることによって、ハッキングを行っているように感じるかもしれません。それ以来、私は別のアプローチを見つけました。ACtrlyetAnotherParam$stateParams
メロット、2014

3
実際、この2つの違いは単なる文脈の問題ではありません。$ stateParamsは、子の状態にさらに多くのparamsが含まれている場合でも、$ stateがその状態に適用すると見なしているURLベースのパラメーターをキャプチャします。$ state.paramsは、すべてのURL +非URLベースのparams取り込むように思われる現在の状態あなたがしているの。あなたがた状態にある場合はparent.child、その$stateParams中にはparentControllerのURLベースのparams評価するparentのものではなく、をparent.childこの問題を参照してください。
Amy.js 2015年

1
一方、$ stateParamsはカスタムオブジェクトやタイプなどを保持できますが、$ state.paramsは「カスタムオブジェクトをプレーンオブジェクトに変換」します。
Amy.js 2015年

2
$stateParams$state.paramsは正しく動作しますが、正しくありません(まだ解決されていない状態の
パラメーター

1
スコープは$ state $ param.paramsを監視できますが、$ stateParamsはできないことがわかりました。なぜか分かりません。
weltschmerz

19

使用するもう1つの理由$state.paramsは、URLベースではない状態です。これは(私の心には)文書化が不十分で、非常に強力です。

URLで公開せずに状態を渡す方法をグーグルで調べているときにこれを発見し、SOの他の場所質問に回答しました。

基本的に、それはこの種の構文を許可します:

<a ui-sref="toState(thingy)" class="list-group-item" ng-repeat="thingy in thingies">{{ thingy.referer }}</a>

こんにちはブラウン、どういうわけか私はそれを動作させることができません、あなたは実用的な例を持っていますか?
storm_buster 2014年

14

編集:この答えはバージョンに対して正しいです0.2.10。@Alexander Vasilyevが指摘したように、バージョンでは機能しません0.2.14

使用するもう1つの理由$state.paramsは、次のようなクエリパラメータを抽出する必要がある場合です。

$stateProvider.state('a', {
  url: 'path/:id/:anotherParam/?yetAnotherParam',
  controller: 'ACtrl',
});

module.controller('ACtrl', function($stateParams, $state) {
  $state.params; // has id, anotherParam, and yetAnotherParam
  $stateParams;  // has id and anotherParam
}

2
もう適用されません。Plunkerを参照してください:plnkr.co/edit/r2JhV4PcYpKJdBCwHIWS?p
Alexander Vasilyev

4

これら2つには多くの違いがあります。しかし、実際に作業しているときに、私はそれを使用する$state.params方が良いことを発見し ました。より多くのパラメーターを使用する場合、これをで維持するのは混乱する可能性があります$stateParams。URLパラメータではない複数のパラメータを使用する$stateと非常に便利です

 .state('shopping-request', {
      url: '/shopping-request/{cartId}',
      data: {requireLogin: true},
      params : {role: null},
      views: {
        '': {templateUrl: 'views/templates/main.tpl.html', controller: "ShoppingRequestCtrl"},
        'body@shopping-request': {templateUrl: 'views/shops/shopping-request.html'},
        'footer@shopping-request': {templateUrl: 'views/templates/footer.tpl.html'},
        'header@shopping-request': {templateUrl: 'views/templates/header.tpl.html'}
      }
    })

3

sthを解決するルート状態があります。$stateresolveパラメータとして渡しても、の可用性は保証されません$state.params。しかし、$stateParams意志を使用します。

var rootState = {
    name: 'root',
    url: '/:stubCompanyId',
    abstract: true,
    ...
};

// case 1:
rootState.resolve = {
    authInit: ['AuthenticationService', '$state', function (AuthenticationService, $state) {
        console.log('rootState.resolve', $state.params);
        return AuthenticationService.init($state.params);
    }]
};
// output:
// rootState.resolve Object {}

// case 2:
rootState.resolve = {
    authInit: ['AuthenticationService', '$stateParams', function (AuthenticationService, $stateParams) {
        console.log('rootState.resolve', $stateParams);
        return AuthenticationService.init($stateParams);
    }]
};
// output:
// rootState.resolve Object {stubCompanyId:...}

"angular"を使用: "〜1.4.0"、 "angular-ui-router": "〜0.2.15"


2

以前の状態パラメーターをあるルートから別のルートに渡すときに私が行った興味深い観察は、$ stateParamsがホイストされ、現在の状態パラメーターで渡された以前のルートの状態パラメーターを上書きすることですが、 $state.param sしないことです。

使用する場合$stateParams

var stateParams        = {};
stateParams.nextParams = $stateParams; //{item_id:123}
stateParams.next       = $state.current.name;

$state.go('app.login', stateParams);
//$stateParams.nextParams on app.login is now:
//{next:'app.details', nextParams:{next:'app.details'}}

$ state.paramsを使用する場合:

var stateParams        = {};
stateParams.nextParams = $state.params; //{item_id:123}
stateParams.next       = $state.current.name;

$state.go('app.login', stateParams);
//$stateParams.nextParams on app.login is now:
//{next:'app.details', nextParams:{item_id:123}}

1

ここでは、この記事で明確に説明します。この$stateサービスは、状態と現在の状態に関連するデータを操作するためのいくつかの便利なメソッドを提供します。現在の状態パラメーターは、$stateサービスのparamsキーでアクセスできます。$stateParamsサービスは、この非常に同じオブジェクトを返します。したがって、この$stateParamsサービスは厳密に便利なサービスであり、$stateサービスです。

そのため、コントローラーが$stateサービスとその便利なサービスの両方を注入することはありません$stateParams$state現在のパラメータにアクセスするためだけにが注入されている場合は、$stateParams代わりに注入するようにコントローラを書き換える必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.