角形路由器获得以前的状态

有办法获取当前状态的以前状态吗?

例如,我想知道在当前状态 B 之前的前一个状态是什么(其中前一个状态应该是状态 A)。

我无法在 ui-router github 文档页面中找到它。

158934 次浏览

Ui-router 在转换之后不会跟踪之前的状态,但是当状态改变时,事件 $stateChangeSuccess会在 $rootScope上广播。

您应该能够捕获该事件的先前状态(from是您要离开的状态) :

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

为了便于阅读,我将我的解决方案(基于 st.salsbury 的答案)放在这里。

将这段代码添加到应用程序的抽象模板中,这样它就可以在每个页面上运行。

$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)
});

跟踪 rootScope 中的更改,非常方便。

在移动到新状态之前,我使用 decision 保存当前状态数据:

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;
}]
}
});
}]);

我使用了类似于恩迪 · 齐亚约诺的方法。

我所做的是在进行转换之前保存当前状态的值。 让我们看一个例子; 想象一下,当点击触发转换的任何东西时,在一个函数中执行:

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

这里的关键是 params 对象(将发送到状态的参数的映射)-> { previousState : { name : $state.current.name } }

注意: 我只“保存”$state 对象的 name 属性,因为这是保存状态所需要的唯一东西。但是我们可以有整个 state 对象。

然后,陈述“随便”的定义是这样的:

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

这里的关键点是 params 对象。

params : {
previousState: null,
}

然后,在这个状态内,我们可以得到这样的前一个状态:

$state.params.previousState.name

这里是一个非常优雅的解决方案从克里斯蒂伦 Ui-router-群集: $previousState

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

previous是一个类似于: { state: fromState, params: fromParams }的对象,其中 from State 是前一个状态,from Params 是 以前的状态参数。

如果你只是需要这个功能并且想在多个控制器中使用它,这是一个跟踪路由历史的简单服务:

  (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;
}
})();

“核心”在哪里。Module (‘ core’)将是应用程序/模块的名称。要求将服务作为控制器的依赖项,然后在控制器中执行: $scope.routeHistory = RouterTracker.getRouteHistory()

你可以这样返回状态:

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

举个例子:

(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);
};


};


})();

在下面的例子中,我创建了一个 decorator(在配置阶段每个应用只运行一次) ,并向 $state服务添加了一个额外的属性,所以这种方法不会向 $rootscope添加 全球性的变量,也不需要向其他服务添加任何额外的依赖关系。

在我的例子中,我需要在用户已经登录时重定向到索引页面,而在用户登录后不需要重定向到前一个“受保护”页面时,重定向到索引页面。

我(为你)使用的唯一未知服务是 authenticationFactoryappSettings:

  • authenticationFactory只管理用户登录。在这种情况下,我只使用一个方法来确定用户是否登录。
  • appSettings是常量,只是为了不在任何地方使用字符串。appSettings.states.loginappSettings.states.register包含登录和注册 URL 的状态名称。

然后在任何 controller/service等你需要注入 $state服务,你可以访问当前和以前的网址像这样:

  • 目前: $state.current.name
  • 上集回顾: $state.previous.route.name

来自 Chrome 控制台:

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

实施方法:

(我使用 angular-ui-router v0.2.17angularjs 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);

一个非常简单的解决方案就是编辑 $ state.current.name 字符串,删除包括最后一个字符串在内的所有内容。”你会得到父州的名字。如果您在状态之间跳转很多次,那么这不起作用,因为它只是解析回当前路径。但是如果你的状态与你实际所在的位置相符,那么这个方法是有效的。

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

在 $stateChangeStart 上向 $state 添加名为{ before }的新属性

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


// Assign {from} to {previous} in $state
$state.previous = from;
...
}

现在,您需要的任何地方都可以使用 $state,这样以前就可以使用 $state 了

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

像这样使用它:

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

好吧,我知道我迟到了,但我是新来的。我正在努力使这个适合这里的 约翰爸爸风格指南。我想让这个可重复使用,所以我创建了一个块。以下是我的想法:

前状态提供者

(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
}
})();

任何对这个代码的批评只会帮助我,所以请让我知道在哪里我可以改进这个代码。

我遇到了同样的问题,找到了最简单的解决方法。

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

或者

//Html
<button type="button" ng-click="goBack()">Back</button>


//JS
$scope.goBack = function() {
window.history.back();
};

(如果希望它更具可测试性,可以将 $window 服务注入到控制器中,并使用 $window.history. back ())。

我保持跟踪以前的状态在 $rootScope,所以无论何时需要我只会调用下面的代码行。

$state.go($rootScope.previousState);

App.js:

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

对于 UI-Router (> = 1.0) ,不推荐使用 StateChange 事件。 要获得完整的迁移指南,请单击此处 < a href = “ https://ui-router.github.io/guide/ng1/ 迁移到 -1 _ 0”rel = “ nofollow noReferrer”>

要获取 UI-Router 1.0 + 中当前状态的以前状态:

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