AngularJS $ location이 경로를 변경하지 않습니다


126

양식을 제출 한 후 페이지의 URL을 변경하는 데 문제가 있습니다.

내 앱의 흐름은 다음과 같습니다.

  1. 경로가 설정되고 URL이 특정 양식 페이지로 인식됩니다.
  2. 페이지로드, 컨트롤러 설정 변수, 지시문이 실행됩니다.
  3. AJAX를 사용하여 특수 양식 제출을 수행하는 특수 양식 지시문이 실행됩니다.
  4. AJAX가 수행 된 후 (Angular는 AJAX를 처리하지 않음) 콜백이 시작되고 지시문 $scope.onAfterSubmit은 위치를 설정하는 함수를 호출합니다 .

문제는 위치를 설정 한 후 아무 일도 일어나지 않는다는 것입니다. 위치 매개 변수도 설정하려고 시도했습니다 /... 아니요. 또한 양식을 제출하지 않으려 고 노력했습니다. 아무것도 작동하지 않습니다.

코드가 onAfterSubmit함수에 도달하는지 테스트 했습니다.

내 유일한 생각은 어떻게 든 함수의 범위가 변경되었다는 것입니다 (지시문에서 호출 된 이후), 그리고 다시 onAfterSubmit범위가 변경되면 어떻게 호출 할 수 있습니까?

여기 내 코드가 있습니다

var Ctrl = function($scope, $location, $http) {
  $http.get('/resources/' + $params.id + '/edit.json').success(function(data) {
    $scope.resource = data;
  });

  $scope.onAfterSubmit = function() {
    $location.path('/').replace();
  };
}
Ctrl.$inject = ['$scope','$location','$http'];

누군가 나를 도와 줄 수 있습니까?



이것은 1 년 전에 만들어진 것임을 명심하십시오.
matsko

1 년의 이익과 함께, 다른 1 년은보다 정확한 정답을 얻습니다.
Jim G.

1
@JimG. 이것은 중복이 아닙니다.이 질문은 4 년 전입니다. 링크 한 것은 2 년 전입니다.
Castro Roy

답변:


298

며칠 전 비슷한 문제가있었습니다. 필자의 경우 문제는 타사 라이브러리 (정확하게 jQuery)로 항목을 변경 한 것입니다.이 경우 함수 호출 및 변수 작동 설정 Angular는 항상 변경 사항이 있음을 인식하지 않으므로 결코 소화되지 않습니다.

$ apply ()는 각도 프레임 워크 외부에서 각도로 표현식을 실행하는 데 사용됩니다. (예 : 브라우저 DOM 이벤트, setTimeout, XHR 또는 타사 라이브러리).

$scope.$apply()위치를 변경 한 직후 사용 replace()하고 Angular에 변경 사항을 알리기 위해 전화하십시오 .


1
매력처럼 작동합니다. 나는 당신의 게시물에 내가 사용하는 코드를 추가했습니다 :) 정말 감사합니다 !!!
matsko

4
$ apply가 앵귤러와 작동하는 방법과 그 문제를 해결하는 방법에 대한 더 나은 아이디어를 얻으려면 해당 yearofmoo.com/2012/10/에
matsko

2
@Skeater 루트 범위를 주입하고 다음과 같이 조작 할 수 있습니다. factory ( 'xyz', [ '$ rootScope', function ($ rootScope) {...}])
F Lekschas

4
$ timeout으로 콜백을 감싸면 범위가 올바르게 적용됩니다.
JasonS

7
JasonS가 말했듯이 $ timeout (function () {// Apply changes here});을 사용하십시오. 여기에는 두 가지 장점이 있습니다. 1) $ scope에 액세스 할 필요가 없습니다. 2) $ apply 이미 실행에 대해 걱정할 필요가 없습니다. 두 번째 이유로 $ timeout을 사용하는 것이 선호되는 방법입니다.
ArneHugo

56

$location.path(...)페이지를 변경하거나 새로 고치는 대신 서비스를 사용했습니다 $window. Angular에서이 서비스는 window객체 에 대한 인터페이스로 사용되며 window객체에는 location위치 또는 URL과 관련된 작업을 처리 할 수 있는 속성 이 포함되어 있습니다 .

예를 들어 다음 window.location과 같이 새 페이지를 지정할 수 있습니다.

$window.location.assign('/');

또는 다음과 같이 새로 고치십시오.

$window.location.reload();

그것은 나를 위해 일했다. 그것은 당신이 기대하는 것과 약간 다르지만 주어진 목표를 위해 작동합니다.


3
나도, $ location.path ()는 URL에 매개 변수가있을 때 리디렉션되지 않습니다
Sudhakar

2
이것이 정답입니다. 참조 여기
어빙

28

나는이 같은 문제가 있었지만 $ location에 대한 나의 호출은 이미 다이제스트 내에 있었다. $ apply ()를 호출하면 이미 처리 중 $ digest가 발생했습니다.

이 트릭은 효과가 있었고 $location컨트롤러 에 주입 해야합니다.

$timeout(function(){ 
   $location...
},1);

왜 이것이 필요한지 모르겠지만 ...


5
이건 나쁜 생각입니다. 다이제스트 내에있는 경우 단계를 확인한 다음 적용을 건너 뛸 수 있습니다. Angular는이를 따라 잡아 URL을 자체적으로 변경합니다 : coderwall.com/p/ngisma
matsko

3
타임 아웃은 더러운 해킹처럼 보입니다. href에 "#"이 포함되어 있으면 $ location.path ()가 예상대로 작동하지 않습니다. 태그에서 href = "#"를 완전히 제거하거나 href = ""로 설정하면 $ timeout을 사용할 필요가 없습니다.
Shankar ARUL-jupyterdata.com

7
$$ phase는 새로운 angularjs 버전에서 변경 될 수 있으므로 액세스하지 않아야하는 개인 변수입니다.
Blaise

7
$ timeout을 사용하는 것은 해킹 일 수 있지만 $$ phase를 사용하는 것이 훨씬 더 큰 해킹입니다. 일반적으로 $$ 접두사를 보거나 만지지 마십시오.
nilskp

3
약 10 시간 동안 임의의 문제가 발생하면이 솔루션이 저에게 효과적이었습니다!
Shakeel

6

$location.path()내 다이제스트가 여전히 실행 중이므로 다음과 같이 내 진술 을 포함해야했습니다 .

       function routeMe(data) {                
            var waitForRender = function () {
                if ($http.pendingRequests.length > 0) {
                    $timeout(waitForRender);
                } else {
                    $location.path(data);
                }
            };
            $timeout(waitForRender);
        }

1
매우 유용한 기능에 감사드립니다!
Bill Effin Murray

나를 위해 문제는 angular-block-ui를 사용하고 있었고 주소 표시 줄 위치를 업데이트하지 못하게하는 것이 었습니다. 우리는 requestFilter가 선택 한 bool로 $ http 요청을 장식하여 block-ui가 특정 호출에서 트리거되지 않았으므로 모든 것이 잘되었습니다.
matao

2

필자의 경우 템플릿 구성에서 선택적 매개 변수 표시기 ( '?')가 누락되었습니다.

예를 들면 다음과 같습니다.

.when('/abc/:id?', {
    templateUrl: 'views/abc.html',
    controller: 'abcControl'
})


$location.path('/abc');

심문 문자가 없으면 경로는 경로 매개 변수를 억제하여 변경되지 않습니다.


그것은 아니다 템플릿 구성 하지만 경로 구성.
Piotr Dobrogost

1

Angular-ui / ui-router를 사용 $state.go('yourstate')하는 사람은 대신 : 를 사용하십시오 $location. 그것은 나를 위해 속임수를했다.


0

이것은 나를 위해 일어났다 (CoffeeScript에서)

 $location.path '/url/path'
 $scope.$apply() if (!$scope.$$phase)

0

내 의견으로는 여기에 많은 답변이 약간 해키처럼 보입니다 (예 : $ apply () 또는 $ timeout).

일반적으로 $ location이 작동하지 않으면 무언가가 각도 방식으로 구현되지 않았 음을 의미합니다.

이 특정 질문에서 문제는 비 각도 AJAX 부분에있는 것 같습니다. 약속이 해결 된 후 $ location을 사용하여 리디렉션을 수행 해야하는 비슷한 문제가있었습니다. 이 예제에서 문제를 설명하고 싶습니다.

이전 코드 :

taskService.createTask(data).then(function(code){
            $location.path("task/" + code);
        }, function(error){});

참고 : taskService.createTask는 약속을 리턴합니다.

$ q-약속을 사용하는 각도 방법 :

let dataPromises = [taskService.createTask(data)];
        $q.all(dataPromises).then(function(response) {
                let code = response[0];
                $location.path("task/" + code);
            }, 
            function(error){});

$ q를 사용하여 약속을 해결하면 리디렉션 문제가 해결되었습니다.

$ q 서비스에 대한 추가 정보 : https://docs.angularjs.org/api/ng/service/ $ q


-8
setTimeout(function() { $location.path("/abc"); },0);

문제를 해결해야합니다.


1
non-setTimeout을 실행하는 것은 매우 나쁜 생각입니다. 그리고 @matsko가 위에서 말했듯이 $ timeout은 최고의 아이디어가 아닙니다.
gonzofish
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.