web-dev-qa-db-ja.com

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

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

次のコードで、http://path/1/paramA/paramBというURLを直接ロードした場合、これはコントローラがロードされたときの動作です。

$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
}

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

112
Merott

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

私の記憶が役立つなら、$stateParamsはオリジナルの$state.paramsより遅く導入されました、そして$state.paramsを続けて書くことを避けるための単純なヘルパーインジェクタのようです。

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

62
Matt Way

$state.paramsを使用するもう1つの理由は、URLベースではない状態のためです。

URLでそれを公開する必要なしに状態を渡す方法についてグーグルしながら、私はちょうどこれを発見し、そして SOの他の場所で質問に答えました

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

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

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

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

$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
}
14
daerin

これら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'}
      }
    })
4

私はsthを解決するルート状態を持っています。 resolveパラメータとして$stateを渡しても$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"

3
jchnxu

あるルートから別のルートに以前の状態パラメーターを渡す際に行った興味深い観察は、$ stateParamsが巻き上げられ、現在の状態パラメーターで渡された以前のルートの状態パラメーターを上書きしますが、$state.paramsを使用しないことです。

$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}}
2
Shaun Tobias

ここ はこの記事の中で明確に説明されています:$stateサービスは現在の状態に関する適切なデータと同様に状態を操作するための多くの役に立つメソッドを提供します。現在の状態パラメータは、paramsキーの$stateサービスでアクセス可能です。 $stateParamsサービスは、これとまったく同じオブジェクトを返します。したがって、$stateParamsサービスは厳密には$stateサービスのparamsオブジェクトにすばやくアクセスするための便利なサービスです。

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

1
pabloRN