web-dev-qa-db-de.com

Legen Sie URL-Abfrageparameter ohne Statusänderung mit Angular ui-router fest

Wie aktualisiere ich die URL der Adressleiste mit einem sich ändernden Abfrageparameter unter Verwendung des AngularJS-UI-Routers, um den Status beim Aktualisieren der Seite beizubehalten?

Momentan verwende ich $state.transitionTo('search', {q: 'updated search term'}), wenn sich die Eingabe ändert, aber das Problem ist, dass dadurch der Controller neu geladen wird, das Fenster neu gezeichnet wird und jeglicher Texteingabefokus verloren geht.

Gibt es eine Möglichkeit, stateParams zu aktualisieren und mit der Fenster-URL zu synchronisieren?

65
Petrus Theron

Ich hatte Probleme mit .transitionTo, bis ich auf i-router 0.2.14 aktualisiert habe. 0.2.14 ändert die Adressleiste korrekt (ohne den Controller neu zu laden) mit einem Aufruf wie folgt:

$state.transitionTo('search', {q: 'updated search term'}, { notify: false });
78
pmont

edit: Habe heute noch ein bisschen damit herumgespielt und festgestellt, dass angular ui-router eine ähnliche Option hat wie der native routerProvider: "reloadOnSearch".

https://github.com/angular-ui/ui-router/wiki/Quick-Reference#options-1

Es ist standardmäßig auf true eingestellt, aber wenn Sie es für Ihren Status auf false einstellen, wird der Status nicht geändert, wenn die Abfrageparameter geändert werden. Sie können dann $location.search(params); oder $location.search('param', value); aufrufen und die URL wird geändert, aber der UI-Router erstellt nicht den gesamten Controller/die gesamte Ansicht neu. Sie müssen wahrscheinlich auch auf die $locationChangeStart -Ereignis im Stammbereich, um Verlaufsaktionen in Ihrer App vor- und zurückzusenden, da dies auch keine Statusänderungen verursacht.

Ich höre auch auf das $stateChangeSuccess -Ereignis im Bereich meines Controllers, um das anfängliche Laden der Seite/Route zu erfassen.

Es gibt einige Diskussionen über Github für die Verwendung dieser Funktion bei Pfadänderungen (nicht nur bei URL-Änderungen): https://github.com/angular-ui/ui-router/issues/125 aber ich habe ' Ich habe das überhaupt getestet, da mein Anwendungsfall spezifisch für Abfragezeichenfolgenparameter war.

In der vorherigen Version meiner Antwort wurde dieses Github-Problem erwähnt:

https://github.com/angular-ui/ui-router/issues/562

Dies ist jedoch ein etwas anderes Problem, bei dem insbesondere ein Modal eines Zustands über einem anderen Zustand angezeigt wird, ohne dass sich der nichtmodale Zustand ändert. Ich habe den Patch in diesem Problem ausprobiert, aber es ist klar, dass er nicht dazu gedacht ist, das Neuladen des gesamten Status bei einer URL-Änderung zu verhindern.

28
Jay Klehr

Update 19. Mai 2015

Ab ui-router 0.2.15 wurde das Problem des erneuten Ladens des Status bei Änderungen von Abfrageparametern behoben. Das neue Update hat jedoch die Vorwärts- und Rückwärtsfunktionen der Verlaufs-API mit Abfrageparametern aufgehoben. Es ist mir nicht gelungen, eine Problemumgehung dafür zu finden.

Original

Jays Antwort funktionierte nicht für mich und auch nicht für jede Menge andere Antworten. Der Versuch, $locationChangeStart Anzuhören, verursachte Probleme beim Hin- und Hergehen im Browserverlauf, da ich den Code zweimal ausführen musste: einmal, als sich der neue Status änderte, und ein anderer, weil $loationChangeStart Ausgelöst wurde.

Ich habe versucht, reloadOnSearch=false Zu verwenden, aber das verhinderte Statusänderungen , auch wenn sich der URL-Pfad änderte. Also habe ich es endlich geschafft, indem ich Folgendes getan habe:

Wenn Sie $location.search() ändern, um die Abfrageparameter zu aktualisieren, verwenden Sie ein "hack" , um das erneute Laden bei der Suche vorübergehend zu deaktivieren, Abfrageparameter festzulegen und das erneute Laden wieder zu aktivieren.

$state.current.reloadOnSearch = false;

$location.search('query', [1,2]);

$timeout(function () {
  $state.current.reloadOnSearch = undefined;
});

Dadurch wird sichergestellt, dass Änderungen an Abfrageparametern den Status nicht neu laden und dass Änderungen am URL-Pfad den Status ordnungsgemäß neu laden.

Der Browserverlauf konnte dadurch jedoch nicht den Status ändern (erforderlich, um zu wissen, wann sich ein Abfrageparameter ändert, um die URL erneut zu lesen), wenn ein Abfrageparameter Teil der URL war. Also musste ich auch den Namen jedes Abfrageparameters zur Eigenschaft url von state hinzufügen.

$locationProvider.html5Mode(true);

$stateProvider
  .state('home', {
    url: '/?param1&param2&param3',
    templateUrl: 'home.html',
    controller: 'homeCtrl as home',
  });

Alle Parameternamen in der URL sind optional, wenn sie auf diese Weise aufgelistet werden. Bei Änderungen an diesen Parameternamen wird der Status jedoch neu geladen, wenn die Schaltflächen "Zurück" und "Vorwärts" im Browser gedrückt werden.

Hoffentlich finden andere dies nützlich und es dauert nicht mehrere Tage, um herauszufinden, wie es geht (wie ich).

27
Steven Lambert