AngularJS $ location không thay đổi đường dẫn


126

Tôi gặp sự cố với việc thay đổi URL của trang sau khi biểu mẫu đã được gửi.

Đây là dòng ứng dụng của tôi:

  1. Các tuyến được đặt, URL được nhận dạng đến một số trang mẫu.
  2. Tải trang, bộ điều khiển đặt biến, chỉ thị được kích hoạt.
  3. Một lệnh biểu mẫu đặc biệt được thực hiện để thực hiện đệ trình biểu mẫu đặc biệt bằng AJAX.
  4. Sau khi AJAX được thực hiện (Angular không chăm sóc AJAX), thì một cuộc gọi lại được thực hiện và lệnh gọi $scope.onAfterSubmitchức năng đặt vị trí.

Vấn đề là sau khi thiết lập vị trí, không có gì xảy ra. Tôi cũng đã thử thiết lập vị trí param thành /... Không. Tôi cũng đã cố gắng không gửi biểu mẫu. Không có gì hoạt động.

Tôi đã thử nghiệm để xem mã có đạt được onAfterSubmitchức năng không (mã này).

Suy nghĩ duy nhất của tôi là bằng cách nào đó phạm vi của hàm bị thay đổi (vì nó được gọi từ một lệnh), nhưng một lần nữa làm thế nào nó có thể gọi onAfterSubmitnếu phạm vi thay đổi?

Đây là mã của tôi

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'];

Ai có thể giúp tôi ra ngoài không?


1
bản sao có thể có của Angular $ location.path không hoạt động
Jim G.

Hãy nhớ rằng điều này đã được tạo ra một năm trước đó.
Matsko

Đúng và với lợi ích của một năm nữa, người khác có câu trả lời được chấp nhận chính xác hơn.
Jim G.

1
@JimG. Đây không phải là một bản sao, câu hỏi này là 4 năm trước, câu hỏi mà bạn liên kết, là 2 năm trước.
Fidel Roy

Câu trả lời:


298

Tôi đã có một vấn đề tương tự một vài ngày trước. Trong trường hợp của tôi, vấn đề là tôi đã thay đổi mọi thứ với thư viện bên thứ 3 (chính xác là jQuery) và trong trường hợp này, mặc dù việc gọi các hàm và cài đặt biến hoạt động, Angular không nhận ra rằng có những thay đổi do đó nó không bao giờ tiêu hóa được.

$ áp dụng () được sử dụng để thực hiện một biểu thức trong góc từ bên ngoài khung góc. (Ví dụ: từ các sự kiện DOM của trình duyệt, setTimeout, XHR hoặc thư viện của bên thứ ba).

Cố gắng sử dụng $scope.$apply()ngay sau khi bạn thay đổi địa điểm và được gọi replace()để cho Angular biết rằng mọi thứ đã thay đổi.


1
Hoạt động như một lá bùa. Tôi đã thêm mã tôi đã sử dụng vào bài đăng của bạn để làm cho nó hoạt động :) Cảm ơn bạn rất nhiều !!!
chiếu

4
Để hiểu rõ hơn về cách ứng dụng $ hoạt động với góc cạnh và cách khắc phục các vấn đề của nó, đây là một liên kết cho năm đóofmoo.com / 2012/10 / trên
thảm

2
@Skeater Bạn chỉ có thể tiêm phạm vi gốc và vận hành trên nó như vậy: nhà máy ('xyz', ['$ rootScope', function ($ rootScope) {...}])
F Lekschas

4
có thể kết thúc cuộc gọi lại của bạn với $ timeout và phạm vi sẽ được áp dụng đúng cách
JasonS

7
Giống như JasonS đã nói, sử dụng $ timeout (function () {// áp dụng các thay đổi tại đây}); Điều này có hai ưu điểm: 1) Bạn không cần truy cập vào phạm vi $. 2) Bạn không phải lo lắng về việc áp dụng $ alredy. Vì lý do thứ 2, sử dụng $ timeout thường là cách tiếp cận được ưa thích.
ArneHugo

56

Thay vì $location.path(...)thay đổi hoặc làm mới trang, tôi đã sử dụng dịch vụ $window. Trong Angular, dịch vụ này được sử dụng làm giao diện cho windowđối tượng và windowđối tượng chứa thuộc tính locationcho phép bạn xử lý các hoạt động liên quan đến vị trí hoặc công cụ URL.

Ví dụ: với window.locationbạn có thể chỉ định một trang mới, như thế này:

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

Hoặc làm mới nó, như thế này:

$window.location.reload();

Nó làm việc cho tôi. Nó hơi khác so với bạn mong đợi nhưng hoạt động cho mục tiêu đã định.


3
tôi cũng vậy, $ location.path () không chuyển hướng khi url có thông số
Sudhakar

2
Đây là câu trả lời chính xác. Xem tại đây
Irving

28

Tôi đã gặp vấn đề tương tự, nhưng cuộc gọi đến địa điểm $ của tôi C ALNG CÓ trong một bản tóm tắt. Gọi $ áp dụng () vừa đưa ra một thông báo $ đã có lỗi trong quy trình.

Thủ thuật này đã hoạt động (và chắc chắn tiêm $locationvào bộ điều khiển của bạn):

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

Mặc dù không biết tại sao điều này lại cần thiết ...


5
Không, đây là một ý tưởng tồi. Chỉ cần kiểm tra pha trong trường hợp thông báo và sau đó bạn có thể bỏ qua việc áp dụng. Angular sẽ bắt kịp với nó và tự thay đổi URL: coderwall.com/p/ngisma
matko

3
thời gian chờ có vẻ như một hack bẩn với tôi. Nếu href của bạn chứa "#", $ location.path () không hoạt động như mong đợi. Chỉ cần xóa hoàn toàn href = "#" trên thẻ của bạn hoặc chỉ cần đặt thành href = "" và bạn sẽ không cần sử dụng $ timeout
Shankar ARUL - jupyterdata.com

7
Giai đoạn $$ là một biến riêng tư mà bạn không nên cố gắng truy cập vì nó có thể thay đổi trong phiên bản angularjs mới.
Blaise

7
Sử dụng $ timeout có thể là một hack, nhưng sử dụng giai đoạn $$ là một hack thậm chí còn lớn hơn. Nói chung, không xem hoặc chạm vào bất cứ thứ gì có tiền tố $$.
nilskp

3
Sau khoảng 10 giờ phá vỡ mọi thứ ngẫu nhiên ... giải pháp này hiệu quả với tôi!
Shakeel

6

Tôi đã phải nhúng $location.path()tuyên bố của mình như thế này vì thông báo của tôi vẫn đang chạy:

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

1
Cảm ơn các chức năng, rất hữu ích!
Bill Effin Murray

Đối với tôi, vấn đề là chúng tôi đã sử dụng angular-block-ui và nó đã ngăn cản việc cập nhật vị trí thanh địa chỉ. chúng tôi đã trang trí yêu cầu $ http bằng một bool mà requestFilter của chúng tôi đã chọn để block-ui không kích hoạt cuộc gọi cụ thể đó, và sau đó mọi thứ đều ổn.
matao

2

Trong trường hợp của tôi, vấn đề là chỉ báo tham số tùy chọn ('?') Bị thiếu trong cấu hình mẫu của tôi.

Ví dụ:

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


$location.path('/abc');

Nếu không có nhân vật thẩm vấn, rõ ràng tuyến đường sẽ không thay đổi triệt tiêu tham số tuyến.


Đây không phải là cấu hình mẫu mà là cấu hình tuyến.
Piotr Dobrogost

1

Nếu bất kỳ ai trong số bạn đang sử dụng Angular-ui / ui-router, hãy sử dụng: $state.go('yourstate')thay vì $location. Nó đã lừa tôi.


0

Điều này cho tôi (trong CoffeeScript)

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

0

Theo ý kiến ​​của tôi, nhiều câu trả lời ở đây có vẻ hơi khó hiểu (ví dụ: $ application () hoặc $ timeout), vì việc loay hoay với $ áp dụng () có thể dẫn đến các lỗi không mong muốn.

Thông thường, khi vị trí $ không hoạt động, điều đó có nghĩa là một cái gì đó không được thực hiện theo cách góc cạnh.

Trong câu hỏi cụ thể này, vấn đề dường như nằm ở phần AJAX không góc cạnh. Tôi gặp một vấn đề tương tự, trong đó việc chuyển hướng sử dụng vị trí $ sẽ diễn ra sau khi một lời hứa được giải quyết. Tôi muốn minh họa vấn đề trên ví dụ này.

Mã cũ:

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

Lưu ý: taskService.createTask trả lại một lời hứa.

$ q - cách thức góc cạnh để sử dụng lời hứa:

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

Sử dụng $ q để giải quyết lời hứa đã giải quyết vấn đề chuyển hướng.

Thông tin thêm về dịch vụ $ q: https://docs.angularjs.org/api/ng/service/ $ q


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

nó sẽ giải quyết vấn đề của bạn


1
Chạy một non-setTimeout là một ý tưởng rất tồi. Và, như @matsko đã nói ở trên, $ timeout không phải là ý tưởng tốt nhất.
gonzofish
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.