AngularJS에서 쿼리 매개 변수를 읽는 가장 간결한 방법은 무엇입니까?


312

AngularJS를 사용하여 URL 쿼리 매개 변수의 값을 읽고 싶습니다. 다음 URL을 사용하여 HTML에 액세스하고 있습니다.

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

예상대로 location.search입니다 "?target=bob". target 값에 액세스하기 위해 웹에 나열된 다양한 예제를 찾았지만 AngularJS 1.0.0rc10에서는 작동하지 않습니다. 특히 다음은 모두입니다 undefined.

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

누구에게 효과가 있는지 아는 사람이 있습니까? ( $location내 컨트롤러에 매개 변수로 사용 하고 있습니다)


최신 정보:

아래에 솔루션을 게시했지만 완전히 만족하지는 않습니다. 에서 문서 개발자 가이드 : 각도 서비스 : $ 위치를 사용하여이 에 대한 다음 상태 $location:

언제 $ location을 사용해야합니까?

응용 프로그램이 현재 URL의 변경에 반응하거나 브라우저에서 현재 URL을 변경하려는 경우 언제든지.

내 시나리오의 경우 내 페이지가 쿼리 매개 변수를 사용하여 외부 웹 페이지에서 열리므로 "현재 URL의 변경에 반응하지 않습니다". 어쩌면 $location작업에 적합한 도구가 아닐 수도 있습니다 (추악한 세부 사항은 아래 답변을 참조하십시오). 따라서이 질문의 제목을 "$ location을 사용하여 AngularJS에서 쿼리 매개 변수를 읽는 방법"에서 변경했습니다. "AngularJS에서 쿼리 매개 변수를 읽는 가장 간결한 방법은 무엇입니까?" 분명히 자바 스크립트와 정규 표현식을 사용하여 구문 분석 할 수 location.search는 있지만 저수준으로 이동하면 프로그래머의 감수성을 떨어 뜨릴 수 있습니다.

그래서 : $location내 대답보다 더 나은 방법이 있습니까? 아니면 간결한 대안이 있습니까?


1
$ location.search () [ 'target']이 작동하지 않아야합니까?
— rob

경로 뒤에 해시가 없기 때문에 작동하지 않습니다. http://127.0.0.1:8080/test.html#?target=bob작동 #하기 전에를 확인하십시오 ?. $location서버로 전송되지 않는 두 번째 수준의 라우팅 방법입니다.
— Daniel F

1
@DanielF @rob, 당신 둘 다 맞아. 현대 브라우저에서 호출 된 $location.search()['target']후 작동 $locationProvider.html5Mode(true)합니다.
— 크리

답변:


199

당신은 삽입 할 수 $ routeParams을 (필요 ngRoute을 컨트롤러로). 문서의 예는 다음과 같습니다.

// 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'}

편집 : $ location 서비스 ( ng) 에서 쿼리 매개 변수를 가져오고 설정할 수 있습니다 . 특히 $ location.search ()search 메소드 입니다.

$ routeParams는 컨트롤러의 초기로드 후 유용성이 떨어집니다. $location.search()언제든지 호출 할 수 있습니다.


1
제안과 링크에 감사드립니다! 페이지를 읽고 작업 샘플을 설정하려고했습니다. 그러나이 경우 라우팅을 사용하고 싶지 않기 때문에 접근법이 나에게 적합하지 않습니다. 그럼에도 불구하고 이것은 유용한 제안이었습니다. 스택 오버플로 담당자가 충분하면이를 찬성합니다.
— Ellis Whitehead

1
@ pkozlowski.opensource의 답변이이 상황에서 더 정확하다고 말하고 싶습니다
— Martín Coll

2
.. 쿼리 매개 변수는 $ routeParams 객체에 일반 경로 매개 변수와 함께 포함되어 있습니다. $ location.search ()를 사용하여 읽거나 설정할 수 있습니다. 답변에 추가하겠습니다.
— Andrew Joslin

5
야 aku이 옳다. 그들은 다른 것입니다. 각도에서 "검색"을 사용하면 쿼리가 해시 (URL 끝)에 추가됩니다. URI에 대한 RFC 사양은 쿼리 매개 변수가 해시 앞에 추가해야한다는 것을 나타냅니다. 따라서 "검색"은 각도 만 외삽하고 해석하는 구조입니다. 그렇기 때문에 실제 URI에 관계없이 모든 요청을 서버 수준에서 한 페이지 (서버 수준)로 위임하기 때문에 HTML5 모드 만 위의 솔루션에서 작동합니다.
— Steven Pena

2
이것은 angularJS에서 route를 사용하려는 경우에만 작동합니다!
— windmaomao

189

html5 모드로 작업하는 것이 좋지만 hashbang 모드에서 작동시킬 수도 있습니다.

간단하게 사용할 수 있습니다 :

$location.search().target

'타겟'검색 매개 변수에 액세스 할 수 있습니다.

참고로, 작동하는 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 () 주위에 괄호가 필요합니까?
— Magne

2
@Magne : 예, 당신은 괄호가 필요 $ location.search는 방법이다 docs.angularjs.org/api/ng/service/$location
— nandin

4
사용하지 않으면 HTML5Mode(true)# / 이후의 매개 변수 만 사용할 수 있거나 처음에 # /로 URL에 추가됩니다.
— Sebastian

21
@nandin : 아뇨. 수 없습니다 괄호 필요 주위를 $location.search() . 이 답변이 왜 거기에 있는지 잘 모르겠습니다.
— Dan Tao

9
@nandin이 "괄호가 필요합니까?"라는 질문을 오해 한 것 같습니다. 당신은 어떻게 검색 후 괄호 아니라의 전체 주위에 사람이 필요합니다 $location.search().
— K. Carpenter

56

내 자신의 질문에 부분 답변을 제공하기 위해 HTML5 브라우저에 대한 실제 샘플은 다음과 같습니다.

<!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>

열쇠는 $locationProvider.html5Mode(true);위와 같이 전화 하는 것이 었습니다 . 이제 열 때 작동합니다 http://127.0.0.1:8080/test.html?target=bob. 구형 브라우저에서는 작동하지 않는다는 사실에 만족하지 않지만 어쨌든이 방법을 사용할 수 있습니다.

구형 브라우저에서 작동하는 대안은 html5mode(true)전화를 끊고 대신 해시 + 슬래시와 함께 다음 주소를 사용하는 것입니다.

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

관련 문서는 개발자 안내서 : Angular Services : $ location 사용 (Google 검색에서 찾지 못한 이상한 것입니다.)에 있습니다.


고마워 쿼리 매개 변수를 읽으려고 머리카락을 뽑아 냈습니다. 위에서 언급 한대로 '정의되지 않음'을 유지했습니다. html5로 모드를 설정했습니다.
— sthomps

의 ng-controller속성 <body>을 MyApp? (으) 로 설정 하지 않아야합니다 .
— Jago

4
Angular 1.3으로 시작하는 것처럼 보입니다. html5Mode를 사용하려면 <base href="https://stackoverflow.com/" />태그를 추가하거나 requireBase: falsehtml5Mode 호출에 다른 매개 변수로 추가 해야합니다. 자세한 내용은 여기
— dae721

17

두 가지 방법으로 수행 할 수 있습니다.

  1. 사용 $routeParams

최상의 권장 솔루션은 $routeParams컨트롤러 에 사용 하는 것입니다. 그것은 필요 ngRoute설치할 모듈을.

   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. 사용 $location.search().

여기에 경고가 있습니다. HTML5 모드에서만 작동합니다. 기본적으로 해시 ( #) 가없는 URL에는 작동하지 않습니다http://localhost/test?param1=abc&param2=def

#/URL 을 추가하여 작동시킬 수 있습니다 .http://localhost/test#/?param1=abc&param2=def

$location.search() 다음과 같은 객체를 반환하려면

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

5
# /
— yonexbat 님

9

$ location.search ()는 HTML5 모드가 켜져 있고 지원되는 브라우저에서만 작동합니다.

이것은 항상 작동합니다 :

$ window.location.search


6

그냥 여름에.

앱이 외부 링크에서로드되는 경우 angular는 이것을 URL 변경으로 감지하지 않으므로 $ loaction.search ()가 빈 객체를 제공합니다. 이 문제를 해결하려면 앱 구성에서 다음을 설정해야합니다 (app.js)

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

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

1
네. 이것은 찾기 힘들었다. 의견 주셔서 감사합니다.
— mikeborgh

2

엘리스 화이트 헤드의 정답입니다. 태그가 $locationProvider.html5Mode(true);있는 응용 프로그램의 기본 URL을 지정 <base href="">하거나 매개 변수 requireBase를false

문서에서 :

html5Mode (history.pushState)를 사용하도록 $ location을 구성하는 경우 태그가있는 응용 프로그램의 기본 URL을 지정하거나 requireBase : false가있는 정의 객체를 $ locationProvider에 전달하여 기본 위치가 필요하지 않도록 $ locationProvider를 구성해야합니다. html5Mode () :

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

1

$ location. $$ search.yourparameter를 사용할 수도 있습니다


18
은 $$search그런 좋은 아이디어 아닙니다 사용하는 내부 변수이다.
— kumarharsh

1

이것은 당신을 도울 수 있습니다

AngularJS에서 쿼리 매개 변수를 읽는 가장 간결한 방법은 무엇입니까

// 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

SPA HTML5Mode의 경우 많은 404 오류 문제가 발생하며이 경우 $ location.search를 작동시킬 필요가 없습니다. 필자의 경우 사용자가 처음에 연결하는 "페이지"에 관계없이 사용자가 내 사이트를 방문 할 때 URL 쿼리 문자열 매개 변수를 캡처하고 로그인하면 해당 페이지로 보낼 수 있습니다. app.run에있는 것들

$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'];
    }
    ...
}

나중에 로그인 후 $ state.go ($ rootScope.initialPage, $ rootScope.initialParams)라고 말할 수 있습니다.


-3

조금 늦었지만 문제가 URL이라고 생각합니다. 대신에

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

너는

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

나는 그것이 효과가 있었을 것이라고 확신한다. Angular는 실제로 # /에 대해 까다 롭습니다.


HTML5 모드를 사용하지 않는 경우에만 해당됩니다. # /가 항상 각도 URL에있는 것은 아닙니다.
— LocalPCGuy

SPA를 구축하는 경우입니다. 내 모든 URL에는 #이 있습니다. HTML5Mode는 1) 404 페이지 새로 고침의 404 및 2) 직접 URL이 작동하지 않음을 의미합니다. 지불하는 높은 가격 인 것 같습니다.
— nuander
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.