Ответ 1
Вместо $state.go() вы также можете использовать $location service.
то есть.
$location.path(URL)
Пожалуйста, позаботьтесь о том, чтобы не использовать # в URL-адресе. Вы также используете window.location.href
Как использовать $state.go()
, если у меня есть только URL?
Или я могу получить состояние на основе URL? (и использовать $state.go(state)
)
Я прошу, потому что мне пришлось перехватить $urlRouterProvider.otherwise()
, чтобы ждать, пока другой плагин загрузит некоторые внешние модули.. и теперь мне нужно продолжить и вызвать URL-адрес, который вызывает otherwise()
Вместо $state.go() вы также можете использовать $location service.
то есть.
$location.path(URL)
Пожалуйста, позаботьтесь о том, чтобы не использовать # в URL-адресе. Вы также используете window.location.href
У меня была аналогичная проблема, и $location
не помогал, поэтому я написал функцию, чтобы получить state
из url
.
NB: я использую вложенные состояния на основе 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);
};
Я был в аналогичной ситуации, то, что я сделал, изменило местоположение на другой путь и reset на текущий после таймаута, подобного этому
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);
Я добавляю полный ответ на это из-за большого количества просмотров.
ПРИМЕЧАНИЕ. location.search() используется только там, где вам нужно обрабатывать URL-адрес с строкой запроса в нем. в противном случае используйте только location.path().
ваше состояние входа в 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()
}
})
ваш 401 (несанкционированный) перехватчик должен выглядеть примерно так...
state.go('login', {fwdPath: location.path(), fwdQueryStringObject: location.search()});
ваша функция входа в систему для входа в систему должна вызывать функцию входа в систему входа в систему. код 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;
}
};
и, наконец, ваши юнит-тесты...
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});