How to use $state.go()
if I have just the URL ?
如果我只有URL,如何使用$ state.go()?
Or can I get a state based on URL? (and than use $state.go(state)
)
或者我可以获得基于URL的状态吗? (而不是使用$ state.go(state))
I'm asking because I had to intercept the $urlRouterProvider.otherwise()
to wait for an other plugin loads some external modules.. and now I need to continue and call the URL that call otherwise()
我问,因为我必须拦截$ urlRouterProvider.otherwise()等待其他插件加载一些外部模块..现在我需要继续并调用其他调用的URL()
4 个解决方案
#1
6
In place of $state.go()
, you can use $location
service as well.
代替$ state.go(),您也可以使用$ location服务。
i.e.
即
$location.path(url)
Please take care of not using # in URL. You can also use window.location.href
请注意不要在URL中使用#。您也可以使用window.location.href
#2
1
I had a similar problem, and $location
wasn't helping, so I wrote a function to get the state
from the url
.
我有一个类似的问题,$ location没有帮助,所以我写了一个函数来从url获取状态。
NB: I am using nested states based on ui-router.stateHelper, so I traverse my nested states object, testing for url matches. It would be slightly different when using dot notation to define nested states - and even easier if you don't use nested states at all!
注意:我正在使用基于ui-router.stateHelper的嵌套状态,所以我遍历我的嵌套状态对象,测试url匹配。使用点表示法来定义嵌套状态时会略有不同 - 如果你根本不使用嵌套状态,那就更容易了!
function goPath (path) {
var target;
var arr = path.match(/\/\w+/g);
var i = 0;
var testState = function (state, i) {
if (state.url === arr[i]) {
target = state;
if (state.children && state.children.length && arr.length > i+1) {
i++;
state.children.forEach( function (childState) {
testState(childState, i);
});
}
}
};
myStatesObj.forEach( function (state) {
testState(state, i);
});
$state.go(target.name);
};
#3
0
I was on a similar situation, what I did is changed the location to a different path and reset it to the current after a timeout like this
我处于类似的情况,我所做的是将位置更改为不同的路径,并在超时之后将其重置为当前状态
var path = $location.path();
$location.path("/");
$timeout(function(){
$location.path(path).replace(); //use .replace() so the empty path won't go to the history
},0);
#4
0
i'm adding a full answer to this due to the high number of views.
由于观看次数很多,我正在为此添加一个完整的答案。
NOTE: location.search() is only used where you need to handle a URL with a query string in it. otherwise use location.path() only.
注意:location.search()仅用于需要处理带有查询字符串的URL的位置。否则只使用location.path()。
your ui.router login state should look something like ...
您的ui.router登录状态应该类似......
.state('login', {
url: '/login',
templateUrl: 'routes/login/login.html',
controller: 'LoginController',
controllerAs: 'loginCtrl',
authenticate: false,
params: {
fwdPath: undefined, // Location to forward to on login success
fwdQueryStringObject: undefined // Query string object to use on login success - retrieved from $location.search()
}
})
your 401 (unauthorised) interceptor should look something like ...
你的401(未经授权的)拦截器应该看起来像......
state.go('login', {fwdPath: location.path(), fwdQueryStringObject: location.search()});
your login controllers login function should call your login service's login function. the code INSIDE the controllers login function should look something like ...
您的登录控制器登录功能应该调用您的登录服务的登录功能。 INSIDE控制器登录功能应该看起来像......
loginService.login(self.username, self.password).then(function (response) {
// local vars prevent unit test failure
var fwdPath = state.params.fwdPath;
var fwdQueryStringObject = state.params.fwdQueryStringObject;
if (response.status === 200) {
timeout(function () {
if (fwdPath != null) {
location.path(fwdPath).search(fwdQueryStringObject);
location.replace();
} else {
state.go('home');
}
}, 400);
} else {
self.error = true;
}
self.pending = false;
}
};
and finally your unit tests ...
最后你的单元测试......
state.params.fwdPath = '/login/list';
state.params.fwdQueryStringObject = {q: 5};
spyOn(location, 'path').and.callThrough();
spyOn(location, 'search').and.callThrough();
...
expect(location.path).toHaveBeenCalledWith('/login/list');
expect(location.search).toHaveBeenCalledWith({q: 5});
#1
6
In place of $state.go()
, you can use $location
service as well.
代替$ state.go(),您也可以使用$ location服务。
i.e.
即
$location.path(url)
Please take care of not using # in URL. You can also use window.location.href
请注意不要在URL中使用#。您也可以使用window.location.href
#2
1
I had a similar problem, and $location
wasn't helping, so I wrote a function to get the state
from the url
.
我有一个类似的问题,$ location没有帮助,所以我写了一个函数来从url获取状态。
NB: I am using nested states based on ui-router.stateHelper, so I traverse my nested states object, testing for url matches. It would be slightly different when using dot notation to define nested states - and even easier if you don't use nested states at all!
注意:我正在使用基于ui-router.stateHelper的嵌套状态,所以我遍历我的嵌套状态对象,测试url匹配。使用点表示法来定义嵌套状态时会略有不同 - 如果你根本不使用嵌套状态,那就更容易了!
function goPath (path) {
var target;
var arr = path.match(/\/\w+/g);
var i = 0;
var testState = function (state, i) {
if (state.url === arr[i]) {
target = state;
if (state.children && state.children.length && arr.length > i+1) {
i++;
state.children.forEach( function (childState) {
testState(childState, i);
});
}
}
};
myStatesObj.forEach( function (state) {
testState(state, i);
});
$state.go(target.name);
};
#3
0
I was on a similar situation, what I did is changed the location to a different path and reset it to the current after a timeout like this
我处于类似的情况,我所做的是将位置更改为不同的路径,并在超时之后将其重置为当前状态
var path = $location.path();
$location.path("/");
$timeout(function(){
$location.path(path).replace(); //use .replace() so the empty path won't go to the history
},0);
#4
0
i'm adding a full answer to this due to the high number of views.
由于观看次数很多,我正在为此添加一个完整的答案。
NOTE: location.search() is only used where you need to handle a URL with a query string in it. otherwise use location.path() only.
注意:location.search()仅用于需要处理带有查询字符串的URL的位置。否则只使用location.path()。
your ui.router login state should look something like ...
您的ui.router登录状态应该类似......
.state('login', {
url: '/login',
templateUrl: 'routes/login/login.html',
controller: 'LoginController',
controllerAs: 'loginCtrl',
authenticate: false,
params: {
fwdPath: undefined, // Location to forward to on login success
fwdQueryStringObject: undefined // Query string object to use on login success - retrieved from $location.search()
}
})
your 401 (unauthorised) interceptor should look something like ...
你的401(未经授权的)拦截器应该看起来像......
state.go('login', {fwdPath: location.path(), fwdQueryStringObject: location.search()});
your login controllers login function should call your login service's login function. the code INSIDE the controllers login function should look something like ...
您的登录控制器登录功能应该调用您的登录服务的登录功能。 INSIDE控制器登录功能应该看起来像......
loginService.login(self.username, self.password).then(function (response) {
// local vars prevent unit test failure
var fwdPath = state.params.fwdPath;
var fwdQueryStringObject = state.params.fwdQueryStringObject;
if (response.status === 200) {
timeout(function () {
if (fwdPath != null) {
location.path(fwdPath).search(fwdQueryStringObject);
location.replace();
} else {
state.go('home');
}
}, 400);
} else {
self.error = true;
}
self.pending = false;
}
};
and finally your unit tests ...
最后你的单元测试......
state.params.fwdPath = '/login/list';
state.params.fwdQueryStringObject = {q: 5};
spyOn(location, 'path').and.callThrough();
spyOn(location, 'search').and.callThrough();
...
expect(location.path).toHaveBeenCalledWith('/login/list');
expect(location.search).toHaveBeenCalledWith({q: 5});