[英]AngularJS ui-router ui-sref causing “Uncaught TypeError: Cannot read property '0' of undefined” error
I have an angularJS component using ui-router with 2 simple route states. 我有一个使用ui-router和2个简单路由状态的angularJS组件。
export default function Routes($stateProvider, $urlRouterProvider, $locationProvider) {
$stateProvider
.state('details', {
url: '/',
template: '<div>...</div>'
})
.state('pdf', {
url: '/viewpdf',
template: '<pdf-viewer></pdf-viewer>'
});
$urlRouterProvider.otherwise(function ($injector, $location) {
var $state = $injector.get("$state");
$state.go("details");
});
}
In the details
view I have a controller that fetches a PDF document, then changes the route state in the callback using $state.go('pdf');
在
details
视图中,我有一个控制器,该控制器获取PDF文档,然后使用$state.go('pdf');
更改回调中的路由状态$state.go('pdf');
In the pdf view I have a ui-sref
link going back to the details view: 在pdf视图中,我有一个
ui-sref
链接,可返回到详细信息视图:
<a ui-sref="details">Back to Details</a>
Intermittently, when I press the Back to Details button, it throws an error from page.js and does not change the route state. 间歇性地,当我按下Back to Details按钮时,它会从page.js引发错误,并且不会更改路由状态。
Uncaught TypeError: Cannot read property '0' of undefined at new Context (page.js:208) at Function.page.replace (page.js:154) at onpopstate (page.js:347) at B (history.min.js:21) at history.min.js:22 Context @ page.js:208 page.replace @ page.js:154 onpopstate @ page.js:347 B @ history.min.js:21 (anonymous) @ history.min.js:22
Looking up the error source I get: (page.js: 208) 查找错误源:(page.js:208)
/**
* Initialize a new "request" `Context`
* with the given `path` and optional initial `state`.
*
* @param {String} path
* @param {Object} state
* @api public
*/
function Context(path, state) {
/* ERROR STACK ENDS ON THIS LINE */
if ('/' == path[0] && 0 != path.indexOf(base)) path = base + path;
/* END */
var i = path.indexOf('?');
this.canonicalPath = path;
this.path = path.replace(base, '') || '/';
this.title = document.title;
this.state = state || {};
this.state.path = path;
this.querystring = ~i ? path.slice(i + 1) : '';
this.pathname = ~i ? path.slice(0, i) : path;
this.params = [];
// fragment
this.hash = '';
if (!~this.path.indexOf('#')) return;
var parts = this.path.split('#');
this.path = parts[0];
this.hash = parts[1] || '';
this.querystring = this.querystring.split('#')[0];
}
The url and view stay at /viewpdf
. 网址和视图位于
/viewpdf
。 If I wait a couple seconds and hit the back button again, it will work correctly. 如果我等了几秒钟然后再次按下返回按钮,它将可以正常工作。
What is causing this behavior, and how do I fix it? 是什么导致此现象,如何解决?
Edit I should clarify, when I refer to the back button, I am referring to the Back to Details button in the /viewpdf
view, not the browser back button. 编辑我应该澄清一下,当我提到“后退”按钮时,我指的是
/viewpdf
视图中的“ 返回详细信息”按钮,而不是浏览器的“后退”按钮。 The browser back button does not exhibit the bug. 浏览器的后退按钮没有出现该错误。
This may get it working: 这可能使其工作:
$state.go('state',{},{
reload: true
});
reload
Docs: reload
文档:
https://ui-router.github.io/ng1/docs/latest/interfaces/transition.transitionoptions.html#reload https://ui-router.github.io/ng1/docs/latest/interfaces/transition.transitionoptions.html#reload
You may also want to add a .then()
to check if your pdf
state is still loading when changing back to details
state: 您可能还想添加
.then()
以在更改回details
状态时检查pdf
状态是否仍在加载:
$state.go(..
.then(
onfulfilled,
onrejected
);
then()
Docs: then()
文件:
https://ui-router.github.io/ng1/docs/latest/interfaces/state.transitionpromise.html#then https://ui-router.github.io/ng1/docs/latest/interfaces/state.transitionpromise.html#then
Update: 更新:
If other nav buttons are placed within the state's component this section of the Docs may be of use. 如果在该州的组件中放置了其他导航按钮,则该文档的这一部分可能有用。
https://github.com/angular-ui/ui-router/wiki#user-content-view-load-events https://github.com/angular-ui/ui-router/wiki#user-content-view-load-events
$rootScope.$on('$viewContentLoaded',
function(event, viewConfig){
// Access to all the view config properties.
// and one special property 'targetView'
// viewConfig.targetView
});
Within this listener you could do something like $scope.loaded = true
with ng-disabled
for nav buttons. 在此侦听器中,您可以执行类似
$scope.loaded = true
并为导航按钮ng-disabled
。
This test code configures a directive for a nav control along with disabling it until the view's DOM is loaded: 此测试代码为nav控件配置了一个指令,并禁用它,直到加载视图的DOM:
angular.module('app',['ui.router'])
.component('componentHome', {
template: '<div>Home Page Contents...</div>',
controller: ['$scope','$state','$rootScope',function($scope,$state,$rootScope){
$scope.loaded = false;
$rootScope.$on('$viewContentLoaded',
function(event, viewConfig){
$scope.loaded = true;
});
}]
})
.component('componentA', {
template: '<div><go></go></div>',
controller: ['$scope','$state','$rootScope',function($scope,$state,$rootScope){
$scope.loaded = false;
$rootScope.$on('$viewContentLoaded',
function(event, viewConfig){
$scope.loaded = true;
});
$scope.stateName = 'b';
$scope.stateLabel = 'B';
}]
})
.component('componentB', {
template: '<div><go></go></div>',
controller: ['$scope','$state','$rootScope',function($scope,$state,$rootScope){
$scope.loaded = false;
$rootScope.$on('$viewContentLoaded',
function(event, viewConfig){
$scope.loaded = true;
});
$scope.stateName = 'a';
$scope.stateLabel = 'A';
}]
})
.directive('go',['$state',function($state){
return {
restrict: 'E',
template: '<button ng-disabled="!loaded" state="stateName">Go to Page {{ stateLabel }}</button>',
link: function(scope,element){
element.on('click',function(e){
$state.go(scope.stateName,{},{
reload: true
}).then(
function(){
// fulfilled
},
function(){
// rejected
}
);
});
}
};
}])
.config(function($stateProvider){
$stateProvider.state('/',{ url: '/', component: 'componentHome' });
$stateProvider.state('a',{ url: '/a', component: 'componentA' });
$stateProvider.state('b',{ url: '/b', component: 'componentB' });
})
;
using html: 使用html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="jquery.js"></script>
<script src="angular.js"></script>
<script src="angular-ui-router.min.js"></script>
<style>
.active{ border: 1px dashed red; }
</style>
</head>
<body ng-app="app">
<a ui-sref="/" ui-sref-active="active">Home Page</a>
<a ui-sref="a" ui-sref-active="active">Page A</a>
<a ui-sref="b" ui-sref-active="active">Page B</a>
<div>
<ui-view></ui-view>
</div>
<script src="app.js"></script>
</body>
</html>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.