AngularJS'de sorgu parametrelerini okumanın en kısa yolu nedir?


312

AngularJS kullanarak URL sorgu parametrelerinin değerlerini okumak istiyorum. HTML'ye şu URL ile erişiyorum:

http://127.0.0.1:8080/test.html?target=bob

Beklendiği gibi, location.searchöyle "?target=bob". Hedef değerine erişmek için , web üzerinde listelenen çeşitli örnekler buldum, ancak bunların hiçbiri AngularJS 1.0.0rc10'da çalışmıyor. Özellikle, aşağıdakilerin hepsi undefined:

  • $location.search.target
  • $location.search['target']
  • $location.search()['target']

Ne işe yarayacağını bilen var mı? ( $locationDenetleyicime parametre olarak kullanıyorum )


Güncelleme:

Aşağıda bir çözüm gönderdim, ancak bundan tamamen memnun değilim. Geliştirici Kılavuzu'ndaki belgeler : Açısal Hizmetler: $ location kullanımı aşağıdakilerle ilgili şunları belirtir $location:

$ Location'ı ne zaman kullanmalıyım?

Uygulamanızın geçerli URL'deki bir değişikliğe tepki vermesi gerektiğinde veya tarayıcıdaki geçerli URL'yi değiştirmek istiyorsanız.

Benim senaryom için, sayfam sorgu parametresi ile harici bir web sayfasından açılacak, bu yüzden kendi başına "geçerli URL'deki bir değişikliğe tepki vermiyorum". Bu yüzden belki $locationiş için doğru araç değil (çirkin ayrıntılar için aşağıdaki cevabıma bakın). Bu nedenle bu sorunun başlığını "$ konumunu kullanarak AngularJS sorgu parametreleri nasıl okunur?" "AngularJS'deki sorgu parametrelerini okumanın en kısa yolu nedir?" Açıkçası javascript ve düzenli ifadeyi ayrıştırmak için kullanabilirdim location.search, ancak bu kadar basit bir şey için bu düşük seviyeye gitmek gerçekten programcı hassasiyetlerimi rahatsız ediyor.

Yani: cevabımda kullandığımdan $locationdaha iyi bir kullanım yolu var mı, yoksa kısa bir alternatif var mı?


1
$ Location.search () ['target'] çalışmaz mı?
soymak

Bu işe yaramaz, çünkü yoldan sonra karma yoktur. http://127.0.0.1:8080/test.html#?target=bobişe yarayacaktı, #önce dikkat edin ?. $locationsunucuya gönderilmeyen ikinci düzey bir yönlendirme yöntemidir.
Daniel F

1
@DanielF @rob, ikiniz de haklısınız. Modern bir tarayıcıda çağrıldıktan $location.search()['target']sonra çalışır $locationProvider.html5Mode(true).
krispy

Yanıtlar:


199

Sen enjekte $ routeParams (gerektirir ngRoute Kumandanızda içine). İşte dokümanlardan bir örnek:

// Given:
// URL: http://server.com/index.html#/Chapter/1/Section/2?search=moby
// Route: /Chapter/:chapterId/Section/:sectionId
//
// Then
$routeParams ==> {chapterId:1, sectionId:2, search:'moby'}

DÜZENLEME: Ayrıca $ location hizmetiyle (içinde kullanılabilir ng), özellikle de searchyöntemi: $ location.search () ile sorgu parametrelerini alıp ayarlayabilirsiniz .

$ routeParams, denetleyicinin ilk yükünden sonra daha az kullanışlıdır; $location.search()her zaman çağrılabilir.


1
Öneri ve bağlantı için teşekkürler! Sayfayı okudum ve çalışan bir örnek oluşturmaya çalıştım. Ancak, yaklaşım benim için işe yaramayacaktır, çünkü bu durumda yönlendirmeyi gerçekten kullanmak istemiyorum. Bu yine de yararlı bir öneri oldu ve yeterli stackoverflow temsilcisi var sonra ben upvote edeceğim.
Ellis Whitehead

1
@ Pkozlowski.opensource'un cevabının bu durumda daha doğru olduğunu söyleyebilirim
Martín Coll

2
Pek değil .. sorgu parametreleri normal rota parametreleriyle $ routeParams nesnesine dahil edilir. ve bunları okuyabilir / $ location.search () ile ayarlayabilirsiniz. Bunu cevaba ekleyeceğim.
Andrew Joslin

5
Jakub haklı. Bunlar farklı şeyler. Açısal olarak "arama" işlevini kullandığınızda, sorguyu karma (URL'nin sonuna) ekler. URI için RFC spesifikasyonu, sorgu parametrelerinin karma değerinin önüne (eklenmemesine) gerekeceğini belirtir. Dolayısıyla "arama", sadece açısalın tahmin edeceği ve yorumlayacağı bir yapıdır. Bu nedenle, gerçek URI'den bağımsız olarak tüm istekleri tek bir sayfaya (sunucu düzeyinde) devrettiğiniz için yukarıdaki çözüm için yalnızca HTML5 modu çalışacaktır.
Steven Pena

2
bu sadece angularJS'de rotayı kullanmak istiyorsanız çalışır!
windmaomao

189

Html5 moduyla çalışmasını sağladığınız iyi, ancak hashbang modunda da çalışması mümkündür.

Sadece şunu kullanabilirsiniz:

$location.search().target

'hedef' arama parametresine erişmek için.

Referans için, burada çalışan jsFiddle: http://web.archive.org/web/20130317065234/http://jsfiddle.net/PHnLb/7/

var myApp = angular.module('myApp', []);

function MyCtrl($scope, $location) {

    $scope.location = $location;
    $scope.$watch('location.search()', function() {
        $scope.target = ($location.search()).target;
    }, true);

    $scope.changeTarget = function(name) {
        $location.search('target', name);
    }
}
<div ng-controller="MyCtrl">

    <a href="#!/test/?target=Bob">Bob</a>
    <a href="#!/test/?target=Paul">Paul</a>
    
    <hr/>    
    URL 'target' param getter: {{target}}<br>
    Full url: {{location.absUrl()}}
    <hr/>
    
    <button ng-click="changeTarget('Pawel')">target=Pawel</button>
    
</div>


2
$ location.search () içindeki parantezlere ihtiyacınız var mı?
Magne

2
@Magne: evet, parantez lazım, $ location.search bir yöntemdir docs.angularjs.org/api/ng/service/$location
nandin

4
Eğer kullanmazsanız, HTML5Mode(true)yalnızca # / işaretinden sonra gelen parametrelerin kullanılabilir olduğunu veya başlangıçta # / ile url'ye ekleneceğini unutmayın.
Sebastian

21
@nandin: No, sen do not parantez gerek etrafında $location.search() . Bu cevabın neden onları oraya koyduğundan emin değilim.
Dan Tao

9
@ Nandin "Parantezlere ihtiyacınız var mı?" Sorusunu yanlış anlamış gibi hissediyorum. Sen yapmak aramadan sonra parantez değil tüm çevresi olanlar gerek $location.search().
K. Carpenter

56

Kendi soruma kısmi bir cevap vermek için HTML5 tarayıcıları için çalışan bir örnek:

<!DOCTYPE html>
<html ng-app="myApp">
<head>
  <script src="http://code.angularjs.org/1.0.0rc10/angular-1.0.0rc10.js"></script>
  <script>
    angular.module('myApp', [], function($locationProvider) {
      $locationProvider.html5Mode(true);
    });
    function QueryCntl($scope, $location) {
      $scope.target = $location.search()['target'];
    }
  </script>
</head>
<body ng-controller="QueryCntl">

Target: {{target}}<br/>

</body>
</html>

Anahtar $locationProvider.html5Mode(true);yukarıdaki gibi aramak oldu . Artık açarken çalışıyorhttp://127.0.0.1:8080/test.html?target=bob . Eski tarayıcılarda çalışmayacağı gerçeğinden memnun değilim, ama yine de bu yaklaşımı kullanabilirim.

Eski tarayıcılarla çalışacak bir alternatif, html5mode(true)çağrıyı bırakmak ve bunun yerine hash + eğik çizgi ile aşağıdaki adresi kullanmaktır:

http://127.0.0.1:8080/test.html#/?target=bob

İlgili belgeler Geliştirici Kılavuzu: Açısal Hizmetler: $ location adresinde (google aramamın bunu bulamadığı garip ...).


Bunun için teşekkürler. Sorgu parametrelerini okumaya çalışırken saçımı çekiyorum. Yukarıda belirtildiği gibi 'tanımsız' tutulmaya devam etti. Html5 için ayar modu çalıştı.
sthomps

Olmamalı ng-controlleröznitelik <body>ayarlanmalıdır MyApp?
Jago

4
Angular 1.3 ile başlamak gibi görünüyor, html5Mode kullanmak için bir <base href="https://stackoverflow.com/" />etiket eklemeniz veya requireBase: falsehtml5Mode çağrısına başka bir parametre olarak eklemeniz gerekir. Ayrıntılar burada
dae721

17

İki şekilde yapılabilir:

  1. kullanma $routeParams

En iyi ve önerilen çözüm $routeParamskumandanızda kullanmaktır . ngRouteModülün kurulmasını gerektirir .

   function MyController($scope, $routeParams) {
      // URL: http://server.com/index.html#/Chapter/1/Section/2?search=moby
      // Route: /Chapter/:chapterId/Section/:sectionId
      // $routeParams ==> {chapterId:'1', sectionId:'2', search:'moby'}
      var search = $routeParams.search;
  }
  1. Kullanma $location.search().

Burada bir uyarı var. Yalnızca HTML5 moduyla çalışır. Varsayılan olarak, içinde hash ( #) bulunmayan URL için çalışmazhttp://localhost/test?param1=abc&param2=def

#/URL'yi ekleyerek çalışmasını sağlayabilirsiniz .http://localhost/test#/?param1=abc&param2=def

$location.search() gibi bir nesneyi döndürmek için:

{
  param1: 'abc',
  param2: 'def'
}

5
# /
yonexbat

9

$ location.search () yalnızca HTML5 modu açıkken ve yalnızca desteklenen tarayıcıda çalışır.

Bu her zaman işe yarar:

$ window.location.search


6

Sadece yaz için.

Uygulamanız harici bağlantılardan yükleniyorsa, açısal bunu bir URL değişikliği olarak algılamaz, böylece $ loaction.search () size boş bir nesne verir. Bunu çözmek için uygulama yapılandırmanızda (app.js) aşağıdakileri ayarlamanız gerekir

.config(['$routeProvider', '$locationProvider', function ($routeProvider,     $locationProvider) 
{
   $routeProvider
      .when('/', {
         templateUrl: 'views/main.html',
         controller: 'MainCtrl'
      })
      .otherwise({
         redirectTo: '/'
      });

      $locationProvider.html5Mode(true);
 }]);

1
Evet. Bu, bulmak için bir acıydı. Yorum için teşekkürler.
mikeborgh

2

Ellis Whitehead'in cevabına bir kesinlik. $locationProvider.html5Mode(true);Bir ile uygulama için temel URL belirtmeden angularjs yeni sürümü ile çalışmaz <base href="">etiketi veya parametreyi ayarlayarak requireBaseiçinfalse

Dokümandan :

$ Location komutunu html5Mode (history.pushState) kullanacak şekilde yapılandırırsanız, etiketi olan uygulama için temel URL'yi belirtmeniz veya $ locationProvider öğesini, requestBase: false ile $ locationProvider adlı bir tanım nesnesini ileterek temel etiket gerektirmeyecek şekilde yapılandırmanız gerekir. html5Mode ():

$locationProvider.html5Mode({
  enabled: true,
  requireBase: false
});

1

$ location da kullanabilirsiniz. $$ search.yourparameter


18
Kullanımı $$search, iyi bir fikir olmayan bir iç değişkendir.
kumarharsh

1

bu sana yardımcı olabilir

AngularJS'de sorgu parametrelerini okumanın en kısa yolu nedir

// Given:
// URL: http://server.com/index.html#/Chapter/1/Section/2?search=moby
// Route: /Chapter/:chapterId/Section/:sectionId
//
// Then
$routeParams ==> {chapterId:1, sectionId:2, search:'moby'}

<!DOCTYPE html>
<html ng-app="myApp">
<head>
  <script src="http://code.angularjs.org/1.0.0rc10/angular-1.0.0rc10.js"></script>
  <script>
    angular.module('myApp', [], function($locationProvider) {
      $locationProvider.html5Mode(true);
    });
    function QueryCntl($scope, $location) {
      $scope.target = $location.search()['target'];
    }
  </script>
</head>
<body ng-controller="QueryCntl">

Target: {{target}}<br/>

</body>
</html>

($location.search()).target

1

Ben bir SPA HTML5Mode 404 hata sorunlarının bir sürü neden olduğunu ve $ location.search bu durumda çalışması için gerekli olmadığını buldum. Benim durumumda, bir kullanıcı siteme geldiğinde, başlangıçta hangi "sayfaya" bağlandıklarına bakılmaksızın, bir URL sorgu dizesi parametresi yakalamak istiyorum ve giriş yaptıktan sonra bunları bu sayfaya gönderebiliyorum. app.run'da bu şeyler

$rootScope.$on('$stateChangeStart', function (e, toState, toParams, fromState, fromParams) {
    if (fromState.name === "") {
        e.preventDefault();
        $rootScope.initialPage = toState.name;
        $rootScope.initialParams = toParams;
        return;
    }
    if ($location.search().hasOwnProperty('role')) {
        $rootScope.roleParameter = $location.search()['role'];
    }
    ...
}

daha sonra giriş yaptıktan sonra $ state.go ($ rootScope.initialPage, $ rootScope.initialParams) diyebilirim


-3

Biraz geç oldu, ancak sorunun URL'niz olduğunu düşünüyorum. Yerine

http://127.0.0.1:8080/test.html?target=bob

sahiptin

http://127.0.0.1:8080/test.html#/?target=bob

Eminim işe yarayacaktır. Açısal # /


Bu yalnızca HTML5 modunu etkinleştirmiyorsanız. # / Her zaman Açısal URL'lerde yoktur.
LocalPCGuy

Bir SPA inşa ediyorsanız. Tüm URL'lerimin # numarası var. HTML5Mode, sayfa yenilemede 1) 404 anlamına gelir ve 2) doğrudan URL'ler çalışmaz. Ödemek için yüksek bir fiyat gibi görünüyor.
nuander
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.