앵귤러는?ui-router를 사용하는 JS는 $state를 계속 발사합니다.ChangeStart 이벤트?
사용자를 인증하기 전까지 모든 ui-router 상태 변경을 차단하려고 합니다.
$rootScope.$on('$stateChangeStart', function (event, next, toParams) {
if (!authenticated) {
event.preventDefault()
//following $timeout is emulating a backend $http.get('/auth/') request
$timeout(function() {
authenticated = true
$state.go(next,toParams)
},1000)
}
})
사용자가 인증될 때까지 모든 상태 변경을 거부하지만, 사용하는 잘못된 URL로 이동하는 경우otherwise()
구성, 메시지와 함께 무한 루프가 나타납니다.
Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!
Watchers fired in the last 5 iterations: [["fn: $locationWatch; newVal: 7; oldVal: 6"],["fn: $locationWatch; newVal: 8; oldVal: 7"],["fn: $locationWatch; newVal: 9; oldVal: 8"],["fn: $locationWatch; newVal: 10; oldVal: 9"],["fn: $locationWatch; newVal: 11; oldVal: 10"]]
아래는 저의 SSCCE입니다.함께 제공합니다.python -m SimpleHTTPServer 7070
그리고 가.localhost:7070/test.html#/bar
네 얼굴에 폭발하는 걸 보는 거지반면에 유일하게 유효한 angularjs 위치로 직접 탐색하면 폭발하지 않습니다.localhost:7070/test.html#/foo
:
<!doctype html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.10/angular-ui-router.min.js"></script>
</head>
<body ng-app="clientApp">
<div ui-view="" ></div>
<script>
var app = angular.module('clientApp', ['ui.router'])
var myRouteProvider = [
'$stateProvider', '$urlRouterProvider',
function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/foo');
$stateProvider.state('/foo', {
url: '/foo',
template: '<div>In Foo now</div>',
reloadOnSearch: false
})
}]
app.config(myRouteProvider)
var authenticated = false
app.run([
'$rootScope', '$log','$state','$timeout',
function ($rootScope, $log, $state, $timeout) {
$rootScope.$on('$stateChangeStart', function (event, next, toParams) {
if (!authenticated) {
event.preventDefault()
//following $timeout is emulating a backend $http.get('/auth/') request
$timeout(function() {
authenticated = true
$state.go(next,toParams)
},1000)
}
})
}
])
</script>
</body>
</html>
이 인증 차단을 수행하기 위해 사용해야 하는 다른 방법이 있습니까?저는 이 인증 차단이 클라이언트 측에서만 가능하다는 것을 알고 있습니다.이 예제에서는 서버 측면을 보여주지 않습니다.
$urlRouterProvider. 그렇지 않으면 $state에 $urlRouterProvider.("/foo)를 조합하여 사용할 때 이 버그가 ui-router로 표시됩니다.시작을 바꿉니다.
이슈 - https://github.com/angular-ui/ui-router/issues/600
Frank Wallis는 좋은 해결책을 제공합니다. 그렇지 않으면 함수를 인수로 사용하는 긴 형태의 방법을 사용합니다.
$urlRouterProvider.otherwise( function($injector, $location) {
var $state = $injector.get("$state");
$state.go("app.home");
});
수고했어 프랭크!
가짜로.이것은 상호작용 문제입니다.$urlRouterProvider
그리고.$stateProvider
. 사용하면 안 됩니다.$urlRouterProvider
나를 위하여otherwise
. 나는 다음과 같은 것을 사용해야 합니다.
$stateProvider.state("otherwise", {
url: "*path",
template: "Invalid Location",
controller: [
'$timeout','$state',
function($timeout, $state ) {
$timeout(function() {
$state.go('/foo')
},2000)
}]
});
또는 투명한 방향 전환:
$stateProvider.state("otherwise", {
url: "*path",
template: "",
controller: [
'$state',
function($state) {
$state.go('/foo')
}]
});
지금 모두:
<!doctype html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.10/angular-ui-router.min.js"></script>
</head>
<body ng-app="clientApp">
<div ui-view="" ></div>
<script>
var app = angular.module('clientApp', ['ui.router'])
var myRouteProvider = [
'$stateProvider',
function($stateProvider) {
$stateProvider.state('/foo', {
url: '/foo',
template: '<div>In Foo now</div>',
reloadOnSearch: false
})
$stateProvider.state("otherwise", {
url: "*path",
template: "",
controller: [
'$state',
function($state) {
$state.go('/foo')
}]
});
}]
app.config(myRouteProvider)
var authenticated = false
app.run([
'$rootScope', '$log','$state','$timeout',
function ($rootScope, $log, $state, $timeout) {
$rootScope.$on('$stateChangeStart', function (event, next, toParams) {
if (!authenticated) {
event.preventDefault()
//following $timeout is emulating a backend $http.get('/auth/') request
$timeout(function() {
authenticated = true
$state.go(next,toParams)
},1000)
}
})
}
])
</script>
</body>
</html>
저도 이런 문제가 있었습니다.아래는 각도 허가 프로젝트에서 영감을 얻은 해결해야 할 코드입니다.
주요 컨셉은 flag()를 추가하는 것입니다.$$finishAuthorize
)를 수동으로 상태로 만들고, 이 플래그에 의해 무한 루프를 끊습니다.우리가 알아야 할 또 다른 점은{notify: false}
옵션의$state.go
, 방송을"$stateChangeSuccess"
수동 이벤트
$rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) {
if (toState.$$finishAuthorize) {
return;
}
if (!authenticated) {
event.preventDefault();
toState = angular.extend({'$$finishAuthorize': true}, toState);
// following $timeout is emulating a backend $http.get('/auth/') request
$timeout(function() {
authenticated = true;
$state.go(toState.name, toParams, {notify: false}).then(function() {
$rootScope.$broadcast('$stateChangeSuccess', toState, toParams, fromState, fromParams);
});
},1000)
}
);
저도 이런 문제가 있었습니다.https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#how-to-make-a-trailing-slash-optional-for-all-routes 에서 후행 슬래시를 선택 사항으로 만들 것을 제안한 것이 코드였던 것으로 드러났습니다.
$urlRouterProvider.rule(function ($injector, $location) {
var path = $location.url();
console.log(path);
// check to see if the path already has a slash where it should be
if (path[path.length - 1] === '/' || path.indexOf('/?') > -1) {
return;
}
if (path.indexOf('?') > -1) {
return path.replace('?', '/?');
}
return path + '/';
});
로 바꿨습니다.
$urlRouterProvider.rule(function ($injector, $location) {
var path = $location.url();
// check to see if the path already has a slash where it should be
if (path[path.length - 1] === '/' || path.indexOf('/?') > -1) {
return;
}
if (path.indexOf('?') > -1) {
$location.replace().path(path.replace('?', '/?'));
}
$location.replace().path(path + '/');
});
새 경로를 반환하지 않고 교체만 해도 상태 변경 시작이 트리거되지 않습니다.
실행 블록을 다음과 같이 변경해 봅니다.
app.run([
'$rootScope', '$log','$state','$interval',
function ($rootScope, $log, $state, $interval) {
var authenticated = false;
$rootScope.$on('$stateChangeStart', function (event, next, toParams) {
if (!authenticated) {
event.preventDefault()
//following $timeout is emulating a backend $http.get('/auth/') request
}
})
var intervalCanceller = $interval(function() {
//backend call
if(call succeeds & user authenticated) {
authenticated = true;
$interval.cancel(intervalCanceller);
$state.go(next, toParams);
}
}, 3000);
}
])
저는 다양한 성공도를 가지고 위의 솔루션을 시도했습니다(Ionic cordova 애플리케이션을 구축하고 있습니다).어느 순간 저는 무한 루프를 얻지 못하고 상태가 바뀌지만, 저는 멍한 시야로 남게 되었습니다.추가했습니다.{ reload:true }
도움이 될 것 같네요해봤습니다.{ notify:false }
그리고.{ notify: true }
그건 도움이 되지 않았습니다
저는 결국 https://stackoverflow.com/a/26800804/409864 에서 나온 대부분의 답변을 사용하게 되었습니다.
$rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) {
// Do not redirect if going to an error page
if (toState.name === 'app.error') {
return;
}
// Do not redirect if going to the login page
if (toState.name === 'app.login') {
return;
}
// Do not redirect if there is a token present in localstorage
var authData = localstorage.getItem('auth');
if (authData.token) {
return;
}
// We do not have a token, are not going to the login or error pages, time to redirect!
event.preventDefault();
console.debug('No auth credentials in localstorage, redirecting to login page');
$state.go('engineerApp.home', {}, {reload: true}); // Empty object is params
});
언급URL : https://stackoverflow.com/questions/25065699/why-does-angularjs-with-ui-router-keep-firing-the-statechangestart-event
'programing' 카테고리의 다른 글
워드프레스의 라우팅 문제 (0) | 2023.09.23 |
---|---|
HSSF로 Excel에서 문자열 값을 읽는 중이지만 두 배입니다. (0) | 2023.09.23 |
해스켈: 문자열로 변환 (0) | 2023.09.23 |
문자열을 포인터 또는 리터럴로 전달할 때 strcmp() 반환 값이 일치하지 않음 (0) | 2023.09.23 |
libavcodec을 이용한 mPEGts 컨테이너의 원시 H264 프레임 (0) | 2023.09.23 |