Leiten Sie einen Status mit UI-Router in AngularJS auf den Standard-Unterzustand um

89

Ich erstelle eine tabulatorbasierte Seite, auf der einige Daten angezeigt werden. Ich verwende UI-Router in AngularJs, um Zustände zu registrieren.

Mein Ziel ist es, beim Laden der Seite eine Standardregisterkarte zu öffnen. Jede Registerkarte hat Unterregisterkarten, und ich möchte, dass beim Ändern der Registerkarten eine Standardunterregisterkarte geöffnet wird.

Ich habe mit der onEnterFunktion getestet und im Inneren verwende ich sie, $state.go('mainstate.substate');aber sie scheint aufgrund von Problemen mit dem Schleifeneffekt nicht zu funktionieren (auf state.go ruft sie den übergeordneten Status auf und so weiter, und sie wird zu einer Schleife).

$stateProvider

.state('main', {
  url: '/main',
  templateUrl: 'main.html',
  onEnter: function($state) {
    $state.go('main.street');
  }
})

.state('main.street', {
  url: '/street',
  templateUrl: 'submenu.html',
  params: {tabName: 'street'}
})

Hier habe ich eine Plunker-Demo erstellt .

Im Moment funktioniert alles, außer dass ich nicht die Standardregisterkarte geöffnet habe und genau das brauche ich.

Vielen Dank für Ihre Vorschläge, Meinungen und Ideen.

Löwe
quelle

Antworten:

172

Update: Ab 1.0 Unterstützt redirectTo out of the box.

https://ui-router.github.io/ng1/docs/latest/interfaces/state.statedeclaration.html#redirectto


Ich habe hier ein Beispiel erstellt .

Diese Lösung kommt von einem netten "Kommentar" zu einem Problem mit der Umleitung unter Verwendung von .when() ( https://stackoverflow.com/a/27131114/1679310 ) und einer wirklich coolen Lösung dafür (von Chris T, aber der ursprüngliche Beitrag war von yahyaKacem).

https://github.com/angular-ui/ui-router/issues/1584#issuecomment-75137373

Erweitern wir also zunächst main mit der Umleitungseinstellung:

$stateProvider
    .state('main', {
      url: '/main',
      templateUrl: 'main.html',
      redirectTo: 'main.street',
    })

Und fügen Sie nur diese wenigen Zeilen hinzu

app.run(['$rootScope', '$state', function($rootScope, $state) {

    $rootScope.$on('$stateChangeStart', function(evt, to, params) {
      if (to.redirectTo) {
        evt.preventDefault();
        $state.go(to.redirectTo, params, {location: 'replace'})
      }
    });
}]);

Auf diese Weise können wir jeden unserer Zustände mit seiner Standardumleitung anpassen ... Überprüfen Sie es hier

BEARBEITEN: Option aus Kommentar von @Alec hinzugefügt, um den Browserverlauf beizubehalten.

Radim Köhler
quelle
4
Dies scheint den Zurück-Knopf zu blockieren.
Scott Sword
6
@ Swordfish0321, um den Zurück-Button zu reparieren, nehmen Sie diese kleine Änderung vor: $state.go(to.redirectTo, params, {location: 'replace'});Dadurch ersetzt der neue Status den vorherigen Status (dh den Status, von dem wir umgeleitet werden) im Verlauf. Siehe Dokumente für $ state.go: angular-ui.github.io/ui-router/site/#/api/…
Alec
2
Ich wollte nur hinzufügen, dass dies sehr nahe an dem lag, was ich tun wollte, aber ich wollte die Standard-URL, anstatt sie zu ersetzen. Dies wurde leicht erreicht, indem ich '$stateChangeStart'zu'$stateChangeSuccess'
Matti Price
6
ui-router 1.0 hat dies unterstützt: ui-router.github.io/guide/ng1/…
Gert-Jan
21

Selbst wenn diese von Radim vorgeschlagene Lösung genau den Job erledigte, musste ich mich an die Unterregisterkarte (Status) jeder Registerkarte erinnern.

Also habe ich eine andere Lösung gefunden, die das Gleiche tut, sich aber auch an jeden Tab-Unterzustand erinnert.

Ich musste nur UI-Router-Extras installieren und die Deep State Redirect- Funktion verwenden:

$stateProvider
  .state('main.street', {
     url: '/main/street',
     templateUrl: 'main.html',
     deepStateRedirect: { default: { state: 'main.street.cloud' } },
  });

Danke dir!

Löwe
quelle
12

Ab Version 1.0 des UI-Routers wird eine redirectToEigenschaft unterstützt . Beispielsweise:

.state('A', {
  redirectTo: 'A.B'
})
BBlackwo
quelle
7

Seit Version 1.0 von ui-router wurde mit IHookRegistry.onBefore () ein Standard-Hook eingeführt, wie im Beispiel Data Driven Default Substate unter http://angular-ui.github.io/ui-router/feature-1.0/ gezeigt. interfaces / Transition.ihookregistry.html # onbefore

// state declaration
{
  name: 'home',
  template: '<div ui-view/>',
  defaultSubstate: 'home.dashboard'
}

var criteria = {
  to: function(state) {
    return state.defaultSubstate != null;
  }
}
$transitions.onBefore(criteria, function($transition$, $state) {
  return $state.target($transition$.to().defaultSubstate);
});
ThmX
quelle
Diese Art von Arbeit für mich, obwohl ich es optimieren musste (auch mit ES6)$transitions.onBefore({ to: state => state.defaultSubstate != null }, trans => trans.router.stateService.target(trans.to().defaultSubstate));
yorch
3
app.config(function($stateProvider,$urlRouterProvider){

    $urlRouterProvider.when("/state","/state/sub-state");

    })
Shubam Yadav
quelle
1
Können Sie erklären, was dies bewirkt und warum es besser ist als die bereits vorhandenen Antworten?
Equalsk
Diese Lösung ist die einfachste und hat bei mir gut funktioniert.
BuffMcBigHuge
Dies ist bei weitem die beste Antwort. Prägnanter als die Verwendung von Änderungsereignissen. Es müssen keine Pakete hinzugefügt werden. Ich weiß nicht, wie das niemandem klar ist. Ich weiß nicht, wie die akzeptierte Antwort so positiv bewertet wurde.
CodeWarrior
1

Wenn jemand hierher kommt, um eine Antwort zu erhalten, wie eine einfache Umleitung für einen Status implementiert werden kann, und wie mir passiert ist, hat er nicht die Möglichkeit, den neuen Router zu verwenden ...

Wenn Sie können, ist die Antwort von @bblackwo natürlich großartig:

$stateProvider.state('A', {
  redirectTo: 'B',
});

Wenn Sie es nicht können, leiten Sie es einfach manuell um:

$stateProvider.state('A', {
  controller: $state => {
    $state.go('B');
  },
});

Ich hoffe, es hilft!

Jose Daniel Vivar Personat
quelle