我正在使用angular ui router来处理我的前端的一些路由。这就是我的路由代码。
// angular config
$stateProvider.state('app', {
templateUrl: '/static/partials/home.html',
controller: 'NavCtrl'
});
$stateProvider.state('app.reader', {
url : '/reader/*path?start&end&column&page',
templateUrl: '/static/partials/reader.html',
resolve : {
panelContent : [
'$state', '$stateParams', '$http',
function ($state, $stateParams, $http) {
alert('resolving panel Content');
return []; // simplest thing possible to illustrate my point
}
]
},
controller: 'ReaderCtrl'
});
/// etc etc
$urlRouterProvider.otherwise('/reader/');
我的html使用多个嵌套视图,我会尝试和尽可能地说明
的index.html
<html>
<div ui-view></div> <!-- /static/partials/home.html gets injected here -->
</html>
/static/home.html
<html>
<!-- some side bar stuff -->
<!-- reader -->
<div ui-view></div> <!-- /static/partials/reader.html gets injected here -->
</html>
所以我有多层次的嵌套
-- index.html
-- home.html
-- reader.html
现在,当我第一次加载页面时,我的警告消息
alert('resolving panel Content');
只发射一次..这是有道理的。但是,让我说我在我的分页中点击“下一页”..
<!-- inside /static/partials/reader.html -->
<uib
pagination total-items= "totalItems"
ng-model= "pageNumber"
ng-change= "pageUpdate"
max-size= "maxPageNumbersDisplayed"
></uib>
这最终会激活我的“ReaderCtrl”中的一个函数
$scope.pageUpdate(page) {
$state.go( '.', {page: page});
}
这会更新网址,而不是像这样的
/#/reader/<my path>
这样的事情
/#/reader/<my_path>?page=2
现在是让我撕掉头发的部分。
我回到路由的阅读器部分的“解决”代码块。
警报消息发生两次。
通过在Web控制台中进行一些调试,我发现订单是
1) alert message in resolve
2) travel through the entirety of ReaderCtrl
3) lots and lots of angular calls
4) alert message (2nd time)
5) travel through entirety of ReaderCtrl a second time.
您可能倾向于知道NavCtrl中发生了什么,但我没有在那里打电话。 NavCtrl中的所有功能都是ReaderCtrl可以继承的功能,以便更新/static/partials/home.html的范围
所以,看起来我好像停留在第3步。
有没有人知道为什么我的解决方案块似乎会被解雇两次?
编辑:
经过多一点调试后,我似乎发现订单就是这样,在“updatePage”函数执行后立即开始。1) first "resolving message"
-- the url has not yet changed
2) second "resolving message"
-- the url appears to have changed very shortly before this message
所以,我想我现在的问题是...... 为什么
$state.go('.', args);
在第一个警报触发前不更改网址,但是在第二个警报处/附近是否更改了网址?
编辑2:无法最终修复我的问题,所以我暂时把它搞砸了......我基本上做了一个函数,我做了我假设$ state.go()在幕后做的事情,并构建了网址。
function _mk_url(args) {
var url = "/reader";
var pageNumber = args.pageNumber || 1;
url += "?page=" + pageNumber;
var columns = args.columns || [];
columns.forEach(function(d) {
url += "&column=" + d;
});
//etc..
return url;
}
var args = {"columns" : ["a", "b", "c"], "pageNumber" : 2};
var url = _mk_url(args);
$location.url(url);
答案 0 :(得分:1)
我遇到了这个问题,发现这是因为我在代码中的其他地方手动调用了我的解析函数。搜索您的代码panelContent()
,您可能会发现它再次被触发的位置。
答案 1 :(得分:0)
我遇到了这个问题。原因是在我的html模板中。我在子元素和父元素中都使用了ui-sref
指令
<li ui-sref="{{r.name}}" ng-class="vm.isCurrent(r)" ng-repeat="r in vm.settingsRoutes">
<span ui-sref="{{r.name}}" ng-bind-html="r.title"></span>
</li>
因此,当我点击span
时,我解雇了stateChange
两次。
答案 2 :(得分:0)
我有同样的错误。
而且我发现我在其中一个解析函数中被$stateParams
更改了。
解决方案是从该对象创建副本,然后对副本执行所需操作。
resolve: {
/** @ngInject */
searchParams: function ($stateParams) {
let params = angular.copy($stateParams); // good
// good:
if (params.pending === undefined) {
params.pending = true;
}
// bad:
if ($stateParams.redirect === 'true') {
$stateParams.pending = false; // this line changing the URL
}
return params;
},
}