2012-06-29 11 views
45

Używam routeProvider do definiowania kontrolerów i szablonów dla moich adresów URL.angularjs - odświeżenie po kliknięciu linku z rzeczywistym URL-em

Po kliknięciu linku, który ma ten sam URL, co rzeczywiste położenie, nic się nie dzieje. Chciałbym wywołać metodę reload(), jeśli użytkownik kliknie na taki link, nawet jeśli lokalizacja się nie zmieniła. Innymi słowy, jeśli ustawię lokalizację na tę samą wartość, chciałbym, aby zachowywała się tak samo, jak gdybym ustawiła ją na inną wartość.

Czy istnieje sposób, aby skonfigurować routeProvider lub locationProvider, aby zrobić to automatycznie? Lub jakie jest właściwe podejście, aby to zrobić? To jest zachowanie stadarda w aplikacjach w obie strony, ale jak to zrobić w angularjs?

Poprosiłem również o to na google groups.

UPDATE:

To pytanie jest coraz wiele poglądów, więc postaram się wyjaśnić, w jaki sposób rozwiązać mój problem.

Utworzyłem niestandardową dyrektywę dotyczącą łączenia w mojej aplikacji, tak jak sugerował to Renan Tomal Fernandes w komentarzach.

angular.module('core.directives').directive('diHref', ['$location', '$route', 
     function($location, $route) { 
    return function(scope, element, attrs) { 
     scope.$watch('diHref', function() { 
      if(attrs.diHref) { 
       element.attr('href', attrs.diHref); 
       element.bind('click', function(event) { 
        scope.$apply(function(){ 
         if($location.path() == attrs.diHref) $route.reload(); 
        }); 
       }); 
      } 
     }); 
    } 
}]); 

Dyrektywa jest następnie używana dla wszystkich linków w mojej aplikacji Chcę mieć tę funkcjonalność.

<a di-href="/home/">Home</a> 

Co ta dyrektywa nie jest to, że ustawia atrybut href dla Ciebie na podstawie di-href atrybutu tak kątowej może obsłużyć go jak zawsze i można zobaczyć link po najechaniu na odnośnik. Ponadto, gdy użytkownik kliknie, a ścieżka łącza będzie taka sama, jak bieżąca ścieżka, przeładuje trasę.

+0

@ public0821 Odpowiedź jest znacznie lepsza niż wybrana odpowiedź – Nayish

+2

Należy uważać na przykładowy kod zamieszczony powyżej, ponieważ powoduje to wycieki pamięci. '$ watch()' zawiera tę instrukcję 'element.bind (" kliknięcie ", funkcja (zdarzenie) {...});" co oznacza, że ​​utworzy funkcję obsługi zdarzeń kliknięcia dla każdego przebiegu obserwatora, nigdy nie zwalniając poprzedniej obsługi kliknięcia. – Kayhadrin

Odpowiedz

20

powinieneś użyć $route.reload(), aby wymusić ponowne załadowanie.

ja nie wiem, czy jest tam „automatyczny” sposób to zrobić, ale można użyć ng kliknąć na te linki

+1

To nie jest bardzo ogólne rozwiązanie. Jeśli chciałbym mieć to zachowanie w całej mojej aplikacji, musiałbym dodać do każdego linku ng-click. – davekr

+4

może można utworzyć dyrektywę dla znacznika "a", który sprawdzi, czy URL docelowy jest taki sam dla łącza i przeładuje trasę $ ... jest to bardzo ogólny i dobry sposób, myślę, że –

56

Możesz dodać _target='_self' na link do strony sił, aby przeładować.

np.

<a href="/Customer/Edit/{{customer.id}}" target="_self">{{customer.Name}}</a> 

Testowałem to w wersji 1.0.5 i 1.2.15 na IE i Firefox. Wydaje się, że działa dobrze.

Oto więcej informacji od AngularJS site:

HTML Link przepisywanie

Podczas korzystania z trybu historia API HTML5, trzeba będzie różne linki w różnych przeglądarkach, ale wszystko, co musisz zrobić, to określić regularne URL linki, takie jak:

<a href="/some?foo=bar">link</a> 

Gdy użytkownik kliknie na ten link,

  • W starszej wersji przeglądarki, zmiany URL do /index.html#!/some?foo=bar
  • w nowoczesnej przeglądarce, zmiany URL do /some?foo=bar

w takich przypadkach Poniżej linki nie są przepisywane; zamiast tego przeglądarka wykona przeładowanie całej strony do oryginalnego łącza.

  • Linki, które zawierają element docelowy przykład: powiązanie <a href="/ext/link?a=b" target="_self">link</a>

  • absolutnych go do innej domeny Przykład: <a href="http://angularjs.org/">link</a>

  • linki zaczynając '/', które prowadzą do różnych podstawy ścieżka, gdy zdefiniowana jest baza Przykład: <a href="/not-my-base/link">link</a>

+1

To spowoduje ponowne załadowanie Cała strona, lepiej byłoby po prostu wywołać metodę 'reload()' np w dyrektywie. – davekr

+2

Ale nie chcę, aby cała strona przeładowała się, tylko kątowy mechanizm routingu. Jeśli ponownie załadujesz całą stronę, jest to niespójne z resztą aplikacji. Jest to rodzaj "lepszego", jaki miałem w głowie. – davekr

+1

To jest całkiem niezła sztuczka, kiedy chcesz przeładować stronę na niektórych linkach ... – Szczups

74

Dodaj/(ukośnik) do zdefiniowanego adresu URL w konfiguracji trasy

spotkałem dziś podobny problem, mam link na mojej stronie internetowej i po kliknięciu go, chcę NG-view ponownie ładuj za każdym razem, aby odświeżyć dane z serwera. Ale jeśli lokalizacja adresu URL nie ulegnie zmianie, kątowe nie przeładuje ng-view.

Wreszcie znalazłem rozwiązanie tego problemu. Na mojej stronie internetowej, ustawić łącza href do:

  • <a href="#/test">test</a>

Ale w config trasy, ustawić:

  • $routeProvider.when('/test/', { controller: MyController, templateUrl:'/static/test.html' });

Różna jest ostatni slash w url. Kiedy po raz pierwszy kliknę href="#/test", przekręć przekierowanie do adresu URL #/test/ i załaduj ng-view. po drugim kliknięciu, ponieważ bieżący URL to #/test/, nie jest równy adresowi URL linku (href="#/test") kliknąłem, więc Angular uruchamia metodę zmiany lokalizacji i ponownie wczytuje widok ng, dodatkowo Angular przekierowuje adres URL do #/test/ ponownie. następnym razem klikam na URL, kanciasty robi to samo ponownie. Właśnie tego chciałem.

Mam nadzieję, że to było dla Ciebie przydatne.

+0

To zadziałało! Dla root'a użyłem href = '#' i $ routeProvider.when ('/', ...) –

+2

Pamiętaj, że to również działa na odwrót, jeśli nie chcesz śledzić ukośników na trasach, możesz zaktualizować twoje linki href mają zamiast tego końcowy ukośnik. –

+0

Interesujące. To działa. Dzięki. – zsong

6

Od @Renan Tomal Fernandes answer. Oto przykład

HTML

<a href="#/something" my-refresh></a> 

JS

angular.module("myModule",[]). 
directive('myRefresh',function($location,$route){ 
    return function(scope, element, attrs) { 
     element.bind('click',function(){ 
      if(element[0] && element[0].href && element[0].href === $location.absUrl()){ 
       $route.reload(); 
      } 
     }); 
    } 
}); 
+3

Nie jest to absolutnie pewne, ale nazwanie tej dyrektywy jako "href" wymusi prawidłowe działanie wszystkich linków bez żadnych zmian w znacznikach. – Lisio

+0

@Lisio - Przetestuj swoją sugestię i działa idealnie. Bardzo dobre rozwiązanie. – Fizzix

+0

Okazało się, że to nie zadziała, jeśli używasz ui-routera zamiast domyślnego modułu trasy –

0

W moim przypadku, jeśli adres URL jest taki sam, nic nie działało w tym $ route.reload(), $ location.path() $ state.transitonTo() itp

Więc moje podejście Korzystanie Dummy Page następująco,

if(oldLocation === newLocation) { 
    // nothing worked ------------ 
    // window.location.reload(); it refresh the whole page 
    // $route.reload(); 
    // $state.go($state.$current, null, { reload: true }); 
    // $state.transitionTo($state.current, $stateParams, {reload:true, inherit: false, notify: false }); 
    // except this one 
    $location.path('/dummy'); 
    $location.path($location.path()); 
    $scope.$apply(); 
} 

Musisz gdzieś zrobić moduł "/ dummy", moduł niczego nie robi, zmienia tylko adres URL, aby następna metoda $ location.path() mogła być zastosowana. Nie przegap $ zakres. $ Apply()

-2

prostu próbowałem dodanie tego

$(window).on('popstate', function(event) { 
//refresh server data 
}); 

i działa dobrze

0

wpadłem na ten problem przed chwilą, z wyjątkiem, że to strona główna "/". Chciałem proste rozwiązanie z mniejszym kodem. Ja po prostu skorzystał z metody .otherwise w $ routProvider

Więc w link html wygląda następująco:

<a href="#/home">Home</a> 

ponieważ nie istnieje strona „/ home” określone w routProvider będzie przekierowywać do '/"metodą" inaczej ". strona z tego zestawu:

.otherwise({ 
redirectTo: '/' 
}); 

Mam nadzieję, że ktoś pomoże

8

dla ludzi, którzy używają AngularUI Router. Możesz użyć czegoś takiego:

<a data-ui-sref="some.state" data-ui-sref-opts="{reload: true}">State</a> 

Zawiadomienie o opcji przeładowania.

znaleźć odpowiedź tutaj: https://stackoverflow.com/a/29384813/426840

+0

Żadne z" rozwiązań "powyżej nie działało dla mnie, ale ten zrobił! – Gerfried

0

Próbowałem rozwiązanie Wittaya za powyższą dyrektywę stosując podejście. W jakiś sposób dyrektywa ciągle popełnia błąd. I skończyć z tego rozwiązania

HTML

<a href="javascript:void(0)" data-ng-click="stateGo('devices')">Devices</a> 

Controller

1

myślę, że to prostsze podejście.

.directive ('a', function ($route, $location) { 
    var d = {}; 
    d.restrict = 'E'; 
    d.link = function (scope, elem, attrs) { 

     // has target 
     if ('target' in attrs) return; 

     // doesn't have href 
     if (!('href' in attrs)) return; 

     // href is not the current path 
     var href = elem [0].href; 
     elem.bind ('click', function() { 
      if (href !== $location.absUrl()) return; 
      $route.reload(); 
     }); 
    }; 
    return d; 
}); 

Zakładając, że chcesz, aby wszystkie podstawowe <a> linki (bez atrybutu target) przeładować na kliknięcia i użyć łącza względne w atrybucie href (np /home zamiast http://example.com/home) Nie trzeba dodawać żadnych specjalnych znaczników do HTML (przydatny przy aktualizacji strony z już napisanym kodem HTML).

Powiązane problemy