AngularUI Router - 在状态更改时滚动到元素

时间:2015-10-10 06:13:30

标签: angularjs angular-ui-router

我在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滚动的最佳方法。

1 个答案:

答案 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);
        }
    }
});

希望这会有所帮助。如果需要,会做一个傻瓜。