我在StackOverflow上搜索了最近五个小时,没有相关的答案能解决我的问题。我有一个UI-Router状态,它加载从自定义指令生成的一长串消息。在许多指向不同消息的地方也链接了此页面。我想滚动到当前选择的消息。
如果我使用$ timeout包围调用,我可以使用$ anchorScroll来使用它。 $timeout(function(){$anchorScroll()};)
但是如果$ timeout没有,那么对$ anchorScroll的调用什么都不做,因为View还没有完全加载。
以下是大部分相关代码。
<message id='message{{message.id}}'
ng-repeat='message in messages'
message='message'
ng-class="{'current':current == 'message{{message.id}}'}" >
</message>
在控制器中,我将当前设置为$scope.current = $location.hash()
。一切正常。
如果我直接加载#/messages#message100
这样的页面,页面将正确滚动。但是,如果从不同的视角我使用如下链接:
<button ui-sref="message-state({'#':'message{{message.id}}'})>
Go To Message {{message.id}}
</button>
由于尚未制作消息列表,因此页面不会自动滚动到正确的锚点。但是通过在$ timeout中调用$ anchorScroll(),我可以使页面滚动。
我不喜欢为此目的使用$ timeout。我知道我不应该在这样的控制器中操纵DOM。
我尝试使用许多$ stateProvider事件注册$ anchorScroll()的调用,例如:
$state.$on('$viewContentLoaded', function(event) {
$anchorScroll();
});
但即使在$ viewContentLoaded触发消息列表时,DOM中也不存在该页面,并且该页面不会滚动。
我是基于$ location.hash()进行UI-Router滚动的最佳方法。
答案 0 :(得分:2)
即使我遇到了类似的情况,经过几天的尝试和错误,我想出了这个。
在ui路由器中,将id参数添加到要启用滚动的状态。
$stateProvider.state('index', {
url: '/',
params: {
id: null
}
})
然后在html中使用ui-sref
<li><a ui-sref="index({id: 'about-us'})" >About Us</a></li>
最后在app.run模块中使用
检测状态更改$rootScope.$on('$viewContentLoaded', function(event){
if ($state.current.name == 'index') {
if($stateParams.id) {
$anchorScroll.yOffset = 150;
$location.hash($stateParams.id);
$timeout(function(){$anchorScroll()}, 1000);
}
}
});
希望这会有所帮助。如果需要,会做一个傻瓜。