`ui-router` $ stateParams ile $ state.params karşılaştırması


116

İle ui-router, URL'deki parametrelere erişmek için bir denetleyiciye $stateveya $stateParamsiçine enjekte etmek mümkündür . Bununla birlikte, parametrelere $stateParamsyalnızca ona erişen denetleyici tarafından yönetilen duruma ve üst durumlarına ait parametreleri ortaya çıkarırken $state.params, tüm alt durumlar dahil tüm parametrelere sahiptir.

Aşağıdaki kod göz önüne alındığında, URL'yi doğrudan yüklersek http://path/1/paramA/paramB, denetleyiciler yüklendiğinde böyle olur:

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

Soru şu ki, fark neden? Ve ne zaman ve neden kullanmanız gerektiği veya bunlardan herhangi birini kullanmaktan kaçınmanız gerektiği konusunda en iyi uygulama yönergeleri var mı?


Böyle mükemmel bir şekilde resmedilmiş bir soru - sormaya çalıştığım şeyi bile bana anlattığınız için teşekkür ederim!
Peter Nixey

Yanıtlar:


65

Belgeler, burada bulgularınızı yinelemektedir: https://github.com/angular-ui/ui-router/wiki/URL-Routing#stateparams-service

Hafızam hizmet ediyorsa $stateParams, orijinalinden daha sonra tanıtıldı $state.paramsve sürekli yazmaktan kaçınmak için basit bir yardımcı enjektör gibi görünüyor $state.params.

Herhangi bir en iyi uygulama yönergesi olduğundan şüpheliyim, ancak bağlam benim için artıyor. Sadece url'ye alınan parametrelere erişmek istiyorsanız, o zaman kullanın $stateParams. Devletin kendisi hakkında daha karmaşık bir şey bilmek istiyorsanız, kullanın $state.


1
Ben kullanarak buldum $state.paramsiçinde ACtrlben olmadığını kontrol etmek istediği için, yetAnotherParamayarlanır. Böylece değilse, bir şeyler yapabilirim. Ben bunu detaya gitmiyorum şey kendine ait bir soru garanti verebilir olarak. Ancak, bir çocuk devlet tarafından tanıtılan ve mevcut durum tarafından tanınmayan bir parametreyi kontrol ederek bir hack yaptığımı hissediyorum $stateParams. O zamandan beri alternatif bir yaklaşım buldum.
Merott

3
Aslında, ikisi arasındaki fark bir bağlam meselesinden daha fazlasıdır. $ stateParams , alt durumu daha fazla parametre içerse bile , $ state'in bu durum için geçerli olduğunu düşündüğü url tabanlı parametreleri yakalar . $ state.params, bulunduğunuz mevcut durumun tüm url + url tabanlı olmayan parametrelerini yakalıyor gibi görünüyor . Eğer durumdaysanız parent.child, o zaman $stateParamsin parentControllerURL tabanlı parametrelerini değerlendirecek parent, ancak parametrelerini değil parent.child. Bu sorunu görün .
Amy.js

1
Öte yandan, $ stateParams özel nesneleri, türleri vb. Koruyabilirken, $ state.params "özel nesneleri düz nesnelere dönüştürür".
Amy.js

2
$stateParamsçözümlemede çalışıyor $state.params, hatalı iken (henüz çözülmemiş durum için parametreler gösterilmiyor)
karaxuna

1
Kapsamın $ state.params'ı izleyebildiğini ancak $ stateParams'ı göremediğini buldum. Neden olduğuna dair hiçbir fikrim yok.
weltschmerz

19

$state.paramsKullanmanın bir başka nedeni de (bana göre) ne yazık ki yetersiz belgelenmiş ve çok güçlü olan URL tabanlı olmayan durumdur.

Bunu URL'de göstermek zorunda kalmadan durumu nasıl geçireceğimi araştırırken keşfettim ve SO'da başka bir yerde bir soruyu yanıtladım .

Temel olarak, bu tür bir sözdizimine izin verir:

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

Merhaba bbrown, bir şekilde çalıştıramıyorum, çalışan bir örnek var mı?
storm_buster

14

DÜZENLEME: Bu yanıt sürüm için doğrudur 0.2.10. @Alexander Vasilyev'in belirttiği gibi sürümde çalışmıyor 0.2.14.

Kullanmanın başka bir nedeni de $state.params, bunun gibi sorgu parametrelerini çıkarmanız gerektiğinde:

$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
Artık geçerli değil. Plunker'a bakın: plnkr.co/edit/r2JhV4PcYpKJdBCwHIWS?p=preview
Alexander Vasilyev

4

Bu ikisi arasında pek çok fark var. Ama pratik olarak çalışırken $state.paramsdaha iyi kullandığını buldum . Daha fazla parametre kullandığınızda, bunu sürdürmek kafa karıştırıcı olabilir $stateParams. URL parametresi olmayan birden çok parametre kullanırsak $stateçok yararlıdır

 .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'yi çözen bir kök durumum var. $stateÇözümleme parametresi olarak geçmek , için kullanılabilirliği garanti etmez $state.params. Ama $stateParamsirade kullanmak .

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:...}

"Açısal": "~ 1.4.0", "açısal-ui-yönlendirici": "~ 0.2.15" kullanma


2

Önceki durum parametrelerini bir rotadan diğerine geçirirken yaptığım ilginç bir gözlem, $ stateParams'ın kaldırılması ve mevcut durum parametreleriyle geçirilen önceki yolun durum parametrelerinin üzerine yazması, ancak $state.params kullanılmamasıdır .

Kullanırken $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 kullanılırken:

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

İşte bu makalede açıklanan açıkça edilir: $stateServis son durumuyla ilgili devlet manipüle yanı sıra ilgili veriler için yararlı çeşitli yöntemler sunar. Mevcut durum parametrelerine, $stateservisteki params anahtarından erişilebilir . $stateParamsHizmet bu çok aynı nesneyi döndürür. Bu nedenle, $stateParamshizmet, hizmet üzerindeki parametreler nesnesine hızlı bir şekilde erişmek için kesinlikle bir kolaylık $statehizmetidir.

Bu nedenle, hiçbir denetleyici hem $statehizmeti hem de kolaylık hizmetini hiçbir zaman enjekte etmemelidir $stateParams. Eğer $stateakım parametrelerini erişmek için sadece enjekte ediliyor, kontrolör enjekte etmek yeniden yazılmalıdır $stateParamsyerine.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.