避免$ timeout()强制在Angular中完成摘要

时间:2014-01-24 10:43:05

标签: javascript jquery angularjs scroll angular-digest

在我的Angular应用程序中,需要发生以下事件序列:

  1. 用户点击按钮
  2. 通过翻转绑定了ng-show的布尔范围变量来显示先前隐藏的div
  3. 新显示的视图位于页面下方,应滚动到视图中。
  4. 目前,滚动不起作用,因为这一切都发生在同一个摘要中。这意味着ng-show绑定变量的新状态没有机会更新DOM。因此,我们尝试滚动到一个元素,就DOM而言,该元素尚未可见。

    通过使用$ timeout包装滚动调用来减轻这种情况,这会强制所有摘要在尝试滚动之前完成。虽然这很有效,但感觉就像是黑客,并且我想知道是否有更好的方法来做到这一点

    这是一个演示问题的小提琴:

    http://jsfiddle.net/fNhnj/3/

    (请注意,此代码是我的真实代码的简化版本,仅用于演示问题,并且我意识到它不遵循最佳实践。请放心,我的实际代码不会在控制器中执行直接DOM操作。)< / p>

    查看:

    <div ng-app="app" ng-controller="MyCtrl" id="container">
        <button ng-click="scroll()">Unhide element and scroll</button> (will not work until $timeout call is uncommented)
        <div style="height:1000px; background-color: #ddddd0">
        </div>
        <div id="target" ng-show="isVisible">section to scroll to</div>
    </div>
    

    JS:

    angular.module("app", [])
    
    .controller('MyCtrl', 
        function MyCtrl($scope, $timeout) {
            $scope.isVisible = false;
            $scope.scroll = function() {
                $scope.isVisible = true;
                // uncommenting the $timeout fixes it, but feels like a hack
                //$timeout(function() {
                    $('body').animate({
                        scrollTop: $("#target").offset().top
                    }, 500);
                //});
            };
        }
    );
    

1 个答案:

答案 0 :(得分:6)

使用$ timeout不是一个大问题,因为您运行的代码不是角度代码,您需要以某种方式与角度进行通信,以便刷新视图。