AngularJS $ konumu yolu değiştirmiyor


126

Bir form gönderildikten sonra sayfanın URL'sini değiştirmeyle ilgili sorun yaşıyorum.

İşte uygulamamın akışı:

  1. Rotalar ayarlandı, URL bir form sayfasına tanındı.
  2. Sayfa yüklenir, denetleyici değişkenleri ayarlar, yönergeler tetiklenir.
  3. AJAX kullanarak özel bir form gönderimi gerçekleştiren özel bir form yönergesi çalıştırılır.
  4. AJAX gerçekleştirildikten sonra (Angular AJAX ile ilgilenmez) bir geri arama başlatılır ve yönerge $scope.onAfterSubmitkonumu belirleyen işlevi çağırır .

Sorun, konumu ayarladıktan sonra hiçbir şeyin olmamasıdır. Konum parametresini de ayarlamayı denedim /... Hayır. Ayrıca formu göndermemeye de çalıştım. Hiç birşey çalışmıyor.

Kodun onAfterSubmitişleve ulaşıp ulaşmadığını test ettim (ki bunu yapıyor).

Tek düşüncem, işlevin kapsamının bir şekilde değiştiğidir (bir yönergeden çağrıldığından beri), ama sonra yine onAfterSubmitkapsam değiştiğinde nasıl çağırabilir ?

İşte kodum

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

birileri bana dışarıda yardım edebilir mi lütfen?



Bunun bundan bir yıl önce yaratıldığını unutmayın.
matsko

Doğru ve fazladan bir yılın faydasıyla, diğeri daha kesin olarak kabul edilmiş bir cevaba sahip.
Jim G.

1
@JimG. bu bir kopya değil, bu soru 4 yıl önce, bağladığınız soru 2 yıl önce.
Castro Roy

Yanıtlar:


298

Birkaç gün önce benzer bir sorun yaşadım. Benim durumumda sorun, bir 3. parti kitaplığıyla (kesin olarak jQuery) bazı şeyleri değiştirmemdi ve bu durumda işlevleri çağırmak ve değişken işleri ayarlamak Angular her zaman değişiklikler olduğunu fark etmiyor, bu yüzden asla sindirmiyor.

$ apply (), bir ifadeyi açısal çerçevenin dışından açısal olarak yürütmek için kullanılır. (Örneğin tarayıcı DOM olayları, setTimeout, XHR veya üçüncü taraf kitaplıklarından).

$scope.$apply()Konumu değiştirdikten ve replace()Angular'a bir şeylerin değiştiğini bildirmek için aradıktan hemen sonra kullanmayı deneyin .


1
Tıkır tıkır çalışıyor. Çalışması için kullandığım kodu gönderinize ekledim :) Çok teşekkür ederim !!!
matsko


2
@Skeater Basitçe kök kapsamını enjekte edebilir ve üzerinde şu şekilde çalışabilirsiniz: factory ('xyz', ['$ rootScope', function ($ rootScope) {...}])
F Lekschas

4
geri
aramanızı

7
JasonS'ın dediği gibi, $ timeout (function () {// değişiklikleri buraya uygulayın}) kullanın; Bunun iki avantajı vardır: 1) $ kapsam'a erişmeniz gerekmez. 2) $ apply alredy çalışması konusunda endişelenmenize gerek yok. İkinci nedenden dolayı, genellikle $ timeout kullanmak tercih edilen yaklaşımdır.
ArneHugo

56

$location.path(...)Sayfayı değiştirmek veya yenilemek yerine servisi kullandım $window. Angular'da bu hizmet, windownesneye arabirim olarak kullanılır ve nesne, konumla veya URL öğeleriyle ilgili işlemleri gerçekleştirmenizi sağlayan windowbir özellik içerir location.

Örneğin window.location, aşağıdaki gibi yeni bir sayfa atayabilirsiniz:

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

Veya şu şekilde yenileyin:

$window.location.reload();

Benim için çalıştı. Beklediğinizden biraz farklı ama verilen amaç için çalışıyor.


3
ben de, url parametresi olduğunda $ location.path () yönlendirme yapmıyor
Sudhakar

2
Bu doğru cevap. Buraya
Irving

28

Aynı sorunu yaşadım, ancak $ location için yaptığım çağrım bir özetin içindeydi. $ Apply () 'ı çağırmak, zaten işlemde hata veren bir $ özet verdi.

Bu numara işe yaradı (ve $locationkontrol cihazınıza enjekte ettiğinizden emin olun ):

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

Bunun neden gerekli olduğu hakkında hiçbir fikrim yok ...


5
Hayır, bu kötü bir fikir. Sadece bir özetin içinde olması durumunda fazı kontrol edin ve ardından başvuruyu atlayabilirsiniz. Angular, onu yakalar ve URL'yi kendi kendine değiştirir: coderwall.com/p/ngisma
matsko

3
zaman aşımı bana kirli bir hack gibi görünüyor. Href'iniz "#" içeriyorsa, $ location.path () beklendiği gibi çalışmaz. Bir etiketinizden tamamen href = "#" öğesini kaldırın veya href = "" olarak ayarlayın ve $ zaman aşımı
Shankar ARUL - jupyterdata.com

7
$$ fazı, yeni bir angularjs sürümünde değişebileceğinden erişmeye çalışmamanız gereken özel bir değişkendir.
Blaise

7
$ Timeout kullanmak bir hack olabilir, ancak $$ phase'i kullanmak daha da büyük bir hack. Genellikle, $$ ön eki olan hiçbir şeyi görüntülemeyin veya dokunmayın.
nilskp

3
Yaklaşık 10 saatlik rastgele şeyler bozulduktan sonra ... bu çözüm benim için çalıştı!
Shakeel

6

İfademi $location.path()bu şekilde yerleştirmek zorunda kaldım çünkü özetim hala çalışıyordu:

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

1
İşlev için teşekkürler, çok kullanışlı!
Bill Effin Murray

benim için sorun, açısal-blok-ui kullanıyor olmamız ve bu, adres çubuğu konumunun güncellenmesini engellemekti. $ http isteğini, requestFilter'ın aldığı bir bool ile süsledik, böylece blok-ui bu belirli çağrıda tetiklenmedi ve sonra her şey yolundaydı.
matao

2

Benim durumumda sorun, şablon yapılandırmamda eksik olan isteğe bağlı parametre göstergesiydi ('?').

Örneğin:

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


$location.path('/abc');

Sorgu karakteri olmadan yol, yol parametresini gizleyerek açıkça değişmeyecektir.


O değil şablon yapılandırma ama rota yapılandırması.
Piotr Dobrogost

1

Herhangi biriniz Angular-ui / ui-yönlendiriciyi kullanıyorsa, $state.go('yourstate')yerine : kullanın $location. Benim için hile yaptı.


0

Bu benim için hata yapıyor (CoffeeScript'te)

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

0

Bana göre buradaki cevapların çoğu biraz karmaşık görünüyor (örneğin, $ apply () veya $ timeout), çünkü $ apply () ile uğraşmak istenmeyen hatalara yol açabilir.

Genellikle, $ konumu çalışmadığında bu, bir şeyin açısal şekilde uygulanmadığı anlamına gelir.

Bu özel soruda, sorun açısal olmayan AJAX kısmında gibi görünüyor. Benzer bir sorun yaşadım, $ location kullanarak yeniden yönlendirmenin bir söz çözüldükten sonra gerçekleşmesi gerekiyordu. Sorunu bu örnekte açıklamak istiyorum.

Eski kod:

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

Not: taskService.createTask bir söz verir.

$ q - vaatleri kullanmanın açısal yolu:

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

Sözü çözmek için $ q kullanmak yeniden yönlendirme sorununu çözdü.

$ Q hizmetiyle ilgili daha fazla bilgi için: https://docs.angularjs.org/api/ng/service/ $ q


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

sorununuzu çözmelidir.


1
SetTimeout dışı bir işlemi çalıştırmak çok kötü bir fikirdir. Ve @matsko'nun yukarıda söylediği gibi, $ timeout en iyi fikir değil.
gonzofish
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.