Pytanie Aktualizowanie adresu URL w Angular JS bez ponownego wyświetlania widoku


Buduję system deski rozdzielczej w AngularJS i mam problem z ustawieniem adresu URL przez $location.path

W naszym panelu mamy kilka widżetów. Po kliknięciu każdy z nich pokazuje większy, zmaksymalizowany widok. Staramy się utworzyć precyzyjne linki, aby umożliwić użytkownikom łączenie się z pulpitem z maksymalizowanym widgetem.

Obecnie mamy 2 trasy, które wyglądają /dashboard/:dashboardId i /dashboard/:dashboardId/:maximizedWidgetId

Gdy użytkownik maksymalizuje widżet, aktualizujemy adres URL za pomocą $location.path, ale powoduje to ponowne renderowanie widoku. Ponieważ mamy wszystkie dane, nie chcemy ponownie ładować całego widoku, chcemy tylko zaktualizować adres URL. Czy istnieje sposób na ustawienie adresu URL bez powodowania ponownego renderowania widoku?

HTML5Mode jest ustawione na true.


76
2017-08-20 14:03


pochodzenie


Jeśli chcesz, aby twoje dane przetrwały zmiany trasy po stronie klienta, dlaczego nie chcesz wprowadzić go do usługi? - Riko


Odpowiedzi:


W rzeczywistości widok będzie renderowany za każdym razem, gdy zmienisz adres URL. Tak działa $ routeProvider w Angular, ale możesz przejść maximizeWidgetId jako typ zapytania, który nie renderuje ponownie widoku.

App.config(function($routeProvider) {
  $routeProvider.when('/dashboard/:dashboardId', {reloadOnSearch: false});
});

Po kliknięciu widgetu w celu maksymalizacji:

<a href="#/dashboard/1?maximizeWidgetId=1">Maximum This Widget</a>
or
$location.search('maximizeWidgetId', 1);

Adres URL w pasku adresu zmieni się na http://app.com/dashboard/1?maximizeWidgetId=1

Możesz nawet oglądać, gdy wyszukiwania zmieniają się w adresie URL (z jednego widżetu na drugi)

$scope.$on('$routeUpdate', function(scope, next, current) {
   // Minimize the current widget and maximize the new one
});

125
2017-08-31 18:32



Jeśli zostanie przyjęta odpowiedź, utworzę osobne pytanie bez żadnych "param" rzeczy. Po prostu głupie pytanie: jak nie renderować ponownie widoku. - OZ_
Myślę kątowy-routery będzie oczywistym wyborem w tej sprawie. - codef0rmer
Używam $routeUpdate zdarzenie. Myślę że $routeChangeStart zostanie wyzwolony, gdy przejdziesz do innej lokalizacji. - lucassp
@lucassp: Oh Yeah. Pozwól mi zaktualizować odpowiedź. - codef0rmer
@ codef0rmer, znalazłem tę odpowiedź więcej niż jeden raz. Dzięki! Świetna odpowiedź, po tak długim czasie! - frosty


Możesz ustawić właściwość reloadOnSearch dla $ routeProvider na wartość false.

Możliwe powielone pytanie: Czy możesz zmienić ścieżkę bez ponownego ładowania kontrolera w AngularJS?

pozdrowienia


8
2017-08-20 14:44



Wygląda na to, że jest duplikatem. Niestety wygląda na to, że mają ten sam problem, o ile jest on częścią ścieżki adresu URL, a nie zmienną zapytania, odświeża się. - Ian Muir
Nie, to nie jest duplikat. - OZ_
Nie jest to duplikat, ponieważ powiązane pytanie dotyczy braku przeładowania kontrolera, a to nie jest ponowne ładowanie szablonu. Rozwiązanie w połączonym pytaniu spowoduje ponowne załadowanie widoku. - Lajos Meszaros


Dla tych, którzy potrzebują zmienić pełną ścieżkę () bez przeładowania kontrolerów

Oto wtyczka: https://github.com/anglibs/angular-location-update

Stosowanie:

$location.update_path('/notes/1');

6
2017-08-12 11:36



dzięki, działa. Ale może nie powinieneś przedłużać oryginalnej lokalizacji $? - rofrol


Używamy Angular UI Router zamiast wbudowanych tras dla podobnego scenariusza. Nie wydaje się, aby ponownie utworzyć instancję kontrolera i zrenderować cały widok.


3
2017-08-31 18:08



Wypróbowałem to i ponownie renderuje widoki dotyczące zmiany trasy. - OZ_
Czy próbowałeś użyć? $state.transitionTo() zamiast $location.path()? - DreamSonic
Nie zmieniam wcale $ location.path (), gdzie powinienem pisać $state.transitionTo() następnie? - OZ_
Cytat: "Gdy użytkownik zmaksymalizuje widget, aktualizujemy adres URL za pomocą funkcji location.path, ale powoduje to ponowne renderowanie widoku." Zamiast zmieniać ścieżkę, powinieneś zadzwonić $state.transitionTo()co z kolei spowoduje aktualizację skrótu adresu URL. - DreamSonic
Pomysł polega na tym, że powinieneś mieć dwa stany zagnieżdżone: jeden na pulpit nawigacyjny i jeden na zmaksymalizowany widżet. Podczas nawigacji ze stanu nadrzędnego do stanu podrzędnego tylko widok podrzędny zostanie ponownie renderowany, a nie widok nadrzędny. - DreamSonic


Zdaję sobie sprawę, że jest to stare pytanie, ale ponieważ znalezienie dobrego rozwiązania zajęło mi dobre półtora dnia, tak się dzieje.

Nie musisz przekształcać ścieżki w ciągi zapytań Jeśli użyjesz kątowy-routery.

Obecnie, z powodu czego można uznać za błąd, ustawienie reloadOnSearch: false na stanie spowoduje zmianę trasy bez ponownego ładowania widoku. Użytkownik lmessinger GitHub był na tyle uprzejmy, aby przedstawić jego wersję demo. Możesz znaleźć link z jego linku powyżej.

Zasadniczo wszystko, co musisz zrobić, to:

  1. Posługiwać się ui-router zamiast ngRoute
  2. W swoich stanach zadeklaruj tych, których pragniesz reloadOnSearch: false

W mojej aplikacji mam widok listy kategorii, z którego można przejść do innej kategorii przy użyciu takiego stanu:

$stateProvider.state('articles.list', {
  url: '{categorySlug}',
    templateUrl: 'partials/article-list.html',
    controller: 'ArticleListCtrl',
    reloadOnSearch: false
  });

to jest to! Mam nadzieję że to pomoże!


3
2018-04-04 12:49





Jak go wdrożyłem:
(moje rozwiązanie głównie w przypadkach, gdy trzeba zmienić całą trasę, a nie podelementy) 

Mam stronę z menu (menuPage) i danych nie należy czyścić w nawigacji (na każdej stronie jest dużo wejść, a użytkownik będzie bardzo niezadowolony, jeśli dane znikną przypadkowo).

  1. wyłącz $ routeProvider
  2. w kontroleru mainPage dodaj dwa elementy div z niestandardowym atrybutem dyrektywy - każda dyrektywa zawiera tylko "templateUrl" i "scope: true"

     <div ng-show="tab=='tab_name'" data-tab_name-page></div>
    
  3. kontroler mainPage zawiera linie do symulacji trasowania:

    if (!$scope.tab && $location.path()) {
        $scope.tab = $location.path().substr(1);
    }
    $scope.setTab = function(tab) {
        $scope.tab = tab;
        $location.path('/'+tab);
    };
    

To wszystko. Trochę brzydko mieć oddzielną dyrektywę dla każdej strony, ale użycie dynamicznej templateUrl (jako funkcji) w dyrektywie powoduje ponowne renderowanie strony (i utratę danych wejściowych).


2
2017-09-04 13:04





Jeśli dobrze zrozumiałem twoje pytanie, chcesz,

  1. Zmaksymalizuj widżet, gdy użytkownik jest włączony / dashboard /: dashboardId i maksymalizuje widżet.
  2. Chcesz, aby użytkownik mógł wrócić do / dashboard /: dashboardId /: maximizedWidgetId i nadal widzieć maksymalizowany widget.

Możesz skonfigurować tylko pierwszą trasę w routerzeConfig i używać RouteParams aby określić, czy zmaksymalizowany widget jest przekazywany w parametrach w kontrolerze skonfigurowanej trasy i maksymalizować wartość przekazywaną jako parametr. Jeśli użytkownik maksymalizuje go za pierwszym razem, udostępnij adres URL temu zmaksymalizowanemu widokowi za pomocą interfejsu maximizedWidgetId w interfejsie użytkownika.

Dopóki używasz $ location (która jest tylko opakowaniem przez macierzysty obiekt lokacji), aby zaktualizować ścieżkę, odświeży widok.


0
2017-08-31 19:37



Nie tylko lokalizacja $ odświeży widok. ng-include będzie również, nawet bez zmiany lokalizacji $. - OZ_
@OZ_ Nie sugerowałem ngInclude, ponieważ jest to zmiana stanu wewnątrz widoku, sugeruję tylko coś podobnego do ng-if, które byłoby związane z funkcją, która może wykryć routeParams - Sivakumar Kailasam


Mam pomysł do wykorzystania

window.history.replaceState ("Object", "Title", "/ new-url");

Jeśli to zrobisz i dojdzie do cyklu trawienia, całkowicie zmieni to wszystko. Jeśli jednak ustawisz go z powrotem w poprawnym URL-u, którego kąt wyjściowy oczekuje, jest w porządku. Tak więc teoretycznie można zapisać poprawny adres URL oczekiwany przez kąt i zresetować go tuż przed poznaniem pożaru trawienia.

Jednak tego nie testowałem.


0
2018-02-21 16:42





Poniższy kod umożliwia zmianę adresu URL bez przekierowania, na przykład: http: // localhost / # / 691? foo? bar? blabla

for(var i=0;i<=1000;i++) $routeProvider.when('/'+i, {templateUrl: "tabPages/"+i+".html",reloadOnSearch: false});

Ale kiedy się zmienisz http: // localhost / # / 692zostaniesz przekierowany.


-2
2018-01-25 21:33



Nie rozumiem, dlaczego tutaj dodałem kolejną odpowiedź. - gsamaras
jest notatką do historii. - abc