Angular – ui-router krijgen vorige toestand

Is er een manier om de vorige toestand van de huidige staat te krijgen?

Bijvoorbeeld Ik zou graag willen weten wat de vorige toestand was voordat huidige stand B (waar vorige toestand staat A zou zijn geweest).

Ik ben niet in staat om het te vinden in ui-router GitHub doc pagina’s.


Antwoord 1, Autoriteit 100%

Ik gebruik vastberadenheid om de huidige status op te slaan voordat u naar de nieuwe staat:

angular.module('MyModule')
.config(['$stateProvider', function ($stateProvider) {
    $stateProvider
        .state('mystate', {
            templateUrl: 'mytemplate.html',
            controller: ["PreviousState", function (PreviousState) {
                if (PreviousState.Name == "mystate") {
                    // ...
                }
            }],
            resolve: {
                PreviousState: ["$state", function ($state) {
                    var currentStateData = {
                        Name: $state.current.name,
                        Params: angular.copy($state.params),
                        URL: $state.href($state.current.name, $state.params)
                    };
                    return currentStateData;
                }]
            }
        });
}]);

Antwoord 2, gezag 89%

ui-router houdt niet bij de vorige toestand als het eenmaal overgangen, maar de gebeurtenis $stateChangeSuccesswordt uitgezonden op de $rootScopeals de status verandert.

Je moet in staat zijn om de vorige status te vangen van die gebeurtenis (fromis de staat je weggaat):

$rootScope.$on('$stateChangeSuccess', function (ev, to, toParams, from, fromParams) {
   //assign the "from" parameter to something
});

Antwoord 3, gezag 67%

Ten behoeve van de leesbaarheid, zal ik mijn oplossing te plaatsen (op basis van anwser stu.salsbury’s) hier.

Voeg deze code toe aan abstracte sjabloon van uw app, zodat het draait op elke pagina.

$rootScope.previousState;
$rootScope.currentState;
$rootScope.$on('$stateChangeSuccess', function(ev, to, toParams, from, fromParams) {
    $rootScope.previousState = from.name;
    $rootScope.currentState = to.name;
    console.log('Previous state:'+$rootScope.previousState)
    console.log('Current state:'+$rootScope.currentState)
});

Houdt van de veranderingen in rootScope. Het is best handig.


Antwoord 4, Autoriteit 9%

In het volgende voorbeeld heb ik een decorator(runs slechts één keer per app configuratie fase) en voegt een extra woning aan $stateservice, zodat deze aanpak niet toevoegen global variabelen om $rootScopeen hoeft niet aan een extra afhankelijkheid toe te voegen aan andere diensten dan $state.

In mijn voorbeeld heb ik nodig om een ​​gebruiker naar de indexpagina, toen hij al in werd ondertekend omleiden en toen hij niet om hem te leiden naar de vorige “beschermde”, pagina na teken in.

De enige onbekende diensten (voor u) die ik gebruik zijn authenticationFactoryen appSettings

  • authenticationFactorynet beheert de gebruiker login. In dit geval i alleen een methode te identificeren als de gebruiker is ingelogd of niet.
  • appSettingsconstanten alleen voor niet overal gebruiken strings. appSettings.states.loginen appSettings.states.registerbevatten de naam van de staat voor de login en registreren url.

Toen in elke controller/ serviceetc u nodig heeft om $statedienst te injecteren en u toegang tot de huidige en de vorige url als volgt uit:

  • Actueel: $state.current.name
  • Vorige: $state.previous.route.name

Van de Chrome-console:

var injector = angular.element(document.body).injector();
var $state = injector.get("$state");
$state.current.name;
$state.previous.route.name;

Uitvoering:

(Ik gebruik angular-ui-router v0.2.17en angularjs v1.4.9)

(function(angular) {
    "use strict";
    function $stateDecorator($delegate, $injector, $rootScope, appSettings) {
        function decorated$State() {
            var $state = $delegate;
            $state.previous = undefined;
            $rootScope.$on("$stateChangeSuccess", function (ev, to, toParams, from, fromParams) {
                $state.previous = { route: from, routeParams: fromParams }
            });
            $rootScope.$on("$stateChangeStart", function (event, toState/*, toParams, fromState, fromParams*/) {
                var authenticationFactory = $injector.get("authenticationFactory");
                if ((toState.name === appSettings.states.login || toState.name === appSettings.states.register) && authenticationFactory.isUserLoggedIn()) {
                    event.preventDefault();
                    $state.go(appSettings.states.index);
                }
            });
            return $state;
        }
        return decorated$State();
    }
    $stateDecorator.$inject = ["$delegate", "$injector", "$rootScope", "appSettings"];
    angular
        .module("app.core")
        .decorator("$state", $stateDecorator);
})(angular);

Antwoord 5, autoriteit 8%

Voeg een nieuwe eigenschap toe met de naam {previous} aan $state op $stateChangeStart

$rootScope.$on( '$stateChangeStart', ( event, to, toParams, from, fromParams ) => {
    // Add {fromParams} to {from}
    from.params = fromParams;
    // Assign {from} to {previous} in $state
    $state.previous = from;
    ...
}

Nu kun je overal waar je maar wilt $state gebruiken, je hebt eerdere beschikbare

previous:Object
    name:"route name"
    params:Object
        someParam:"someValue"
    resolve:Object
    template:"route template"
    url:"/route path/:someParam"

En gebruik het zo:

$state.go( $state.previous.name, $state.previous.params );

Antwoord 6, autoriteit 6%

Ik zit met hetzelfde probleem en vind de gemakkelijkste manier om dit te doen…

//Html
<button type="button" onclick="history.back()">Back</button>

OF

//Html
<button type="button" ng-click="goBack()">Back</button>
//JS
$scope.goBack = function() {
  window.history.back();
};

(Als u wilt dat het meer testbaar is, injecteert u de $window-service in uw controller en gebruikt u $window.history.back()).


Antwoord 7, autoriteit 5%

Ik gebruik een vergelijkbare benadering als wat Endy Tjahjono doet.

Wat ik doe, is de waarde van de huidige status opslaan voordat ik een overgang maak.
Laten we eens kijken naar een voorbeeld; stel je dit voor in een functie die wordt uitgevoerd wanneer wordt geklikt op wat de overgang ook activeert:

$state.go( 'state-whatever', { previousState : { name : $state.current.name } }, {} );

De sleutel hier is het params-object (een kaart van de parameters die naar de staat worden verzonden) -> { previousState : { name : $state.current.name } }

Opmerking: merk op dat ik alleen het name-attribuut van het $state-object “opsla”, omdat dit het enige is dat ik nodig heb om de staat op te slaan. Maar we zouden het hele staatsobject kunnen hebben.

Vermeld dan “wat dan ook” als volgt is gedefinieerd:

.state( 'user-edit', {
  url : 'whatever'
  templateUrl : 'whatever',
  controller: 'whateverController as whateverController',
  params : {
    previousState: null,
  }
});

Hier is het belangrijkste punt het params-object.

params : {
  previousState: null,
}

Dan, binnen die staat, kunnen we de vorige staat als volgt krijgen:

$state.params.previousState.name

Antwoord 8, autoriteit 4%

Hier is een echt elegante oplossing van Chris Thielen ui-router-extras: $previousState

var previous = $previousState.get(); //Gets a reference to the previous state.

previousis een object dat eruitziet als: { state: fromState, params: fromParams }waarbij fromState de vorige staat is en fromParams
de vorige statusparameters.


Antwoord 9, autoriteit 3%

Ok, ik weet dat ik te laat ben op het feest hier, maar ik ben nieuw bij hoekig. Ik probeer dit hier in de John Papa-stijlgidste laten passen. Ik wilde dit herbruikbaar maken, dus ik heb het in een blok gemaakt. Dit is wat ik bedacht:

vorigeStateProvider

(function () {
'use strict';
angular.module('blocks.previousState')
       .provider('previousState', previousStateProvider);
previousStateProvider.$inject = ['$rootScopeProvider'];
function previousStateProvider($rootScopeProvider) {
    this.$get = PreviousState;
    PreviousState.$inject = ['$rootScope'];
    /* @ngInject */
    function PreviousState($rootScope) {
        $rootScope.previousParms;
        $rootScope.previousState;
        $rootScope.currentState;
        $rootScope.$on('$stateChangeSuccess', function (ev, to, toParams, from, fromParams) {
            $rootScope.previousParms = fromParams;
            $rootScope.previousState = from.name;
            $rootScope.currentState = to.name;
        });
    }
}
})();

core.module

(function () {
'use strict';
angular.module('myApp.Core', [
    // Angular modules 
    'ngMessages',
    'ngResource',
    // Custom modules 
    'blocks.previousState',
    'blocks.router'
    // 3rd Party Modules
]);
})();

core.config

(function () {
'use strict';
var core = angular.module('myApp.Core');
core.run(appRun);
function appRun(previousState) {
    // do nothing. just instantiating the state handler
}
})();

Kritiek op deze code is alleen maar nuttig voor mij, dus laat me alstublieft weten waar ik deze code kan verbeteren.


Antwoord 10

Als je deze functionaliteit alleen nodig hebt en deze in meer dan één controller wilt gebruiken, is dit een eenvoudige service om de routegeschiedenis bij te houden:

 (function () {
  'use strict';
  angular
    .module('core')
    .factory('RouterTracker', RouterTracker);
  function RouterTracker($rootScope) {
    var routeHistory = [];
    var service = {
      getRouteHistory: getRouteHistory
    };
    $rootScope.$on('$stateChangeSuccess', function (ev, to, toParams, from, fromParams) {
      routeHistory.push({route: from, routeParams: fromParams});
    });
    function getRouteHistory() {
      return routeHistory;
    }
    return service;
  }
})();

waarbij de ‘core’ in .module(‘core’) de naam van uw app/module zou zijn. Vereist de service als een afhankelijkheid van uw controller, dan kunt u in uw controller het volgende doen: $scope.routeHistory = RouterTracker.getRouteHistory()


Antwoord 11

Ik houd eerdere statussen in $rootScopebij, dus wanneer ik dat nodig heb, bel ik gewoon de onderstaande regel code.

$state.go($rootScope.previousState);

In App.js:

$rootScope.$on('$stateChangeSuccess', function(event, to, toParams, from, fromParams) {
  $rootScope.previousState = from.name;
});

Antwoord 12

Een echt eenvoudige oplossing is gewoon om de $ State.Current.name string te bewerken en alles uit te knippen, inclusief en na de laatste ‘.’ – U krijgt de naam van de bovenliggende toestand. Dit werkt niet als je veel spuit tussen staten omdat het gewoon het huidige pad parseert. Maar als uw staten overeenkomen met waar u eigenlijk bent, dan werkt dit.

var previousState = $state.current.name.substring(0, $state.current.name.lastIndexOf('.'))
$state.go(previousState)

Antwoord 13

Voor UI-Router (& GT; = 1.0) zijn de gebeurtenissen uit Statechange verouderd.
Klik voor volledige migratiegids op hier

Om de vorige status van de huidige staat in UI-Router 1.0+ te krijgen:

app.run(function ($transitions) {
    $transitions.onSuccess({}, function (trans) {
         // previous state and paramaters
         var previousState = trans.from().name;
         var previousStateParameters = trans.params('from');
    });
});

Antwoord 14

U kunt de staat op deze manier retourneren:

$state.go($state.$current.parent.self.name, $state.params);

Een voorbeeld:

(function() {
    'use strict'
    angular.module('app')
        .run(Run);
    /* @ngInject */
    function Run($rootScope, $state) {
        $rootScope.back = function() {
            $state.go($state.$current.parent.self.name, $state.params);
        };
    };
})();

Other episodes