用于检测ng-repeat容器内滚动的Angular指令

时间:2017-04-02 16:11:25

标签: angularjs angularjs-directive

在我的Angular应用程序中,我根据提供给类似问题here的答案创建了一个简单的指令,以便在滚动上执行某些操作。

以下是我的onScroll指令的代码:

(function() {
    'use strict';

    angular
        .module('proverbial')
        .directive('onScroll', Directive);

    Directive.$inject = [ '$document' ];
    function Directive($document) {

        var directive = {
            link: link,
            restrict: 'A'
        };
        return directive;

        function link(scope, element, attrs) {  
            element.bind('scroll', function(e) {
                console.warn(e)
                if (element[ 0 ].scrollTop + element[ 0 ].offsetHeight >= element[ 0 ].scrollHeight) {
                    scope.$apply(attr.onScroll);
                }
            });
        }
    }
})();

这将在以下HTML模板中使用:

<div class="absolute" on-scroll="vm.totalDisplayed += 100">
    <span class="card hover"
    ng-repeat="proverb in vm.proverbs | limitTo: vm.totalDisplayed">
        <a>{{proverb.text | maxLength: 90}}</a>
    </span>
</div>

目的是在页面滚动上不断增加vm.totalDisplayed,以创建类似于延迟加载的效果。

但是,当我向下滚动到已经加载了ng-repeat的内容的末尾时,没有任何反应。 console.warn(e)永远不会触发。

在浏览器控制台上,我可以看到包含<div class="absolute" on-scroll="vm.totalDisplayed += 100">确实向上滚动浏览器的窗口。

缺少什么?

2 个答案:

答案 0 :(得分:0)

您的代码中有一个小错误:

if (element[ 0 ].scrollTop + element[ 0 ].offsetHeight >= element[ 0 ].scrollHeight) {
    scope.$apply(attr.onScroll);
}

attr未定义。应该是attrs

此外,我无法重现这个问题。我已经从您的代码中创建了一个Plunker,警告显示正常。我觉得奇怪的是,我无法让vm.totalDisplayed += 100工作。 vm.totalDisplayed = vm.totalDisplayed + 100虽然有效。

http://plnkr.co/edit/ooMFG4ZAZzxJf9zuChyA

答案 1 :(得分:0)

尽管@Tom正确地指出我的指令中有一个合成错误,但事实证明这不是问题。

问题是我附加指令的元素实际上并没有因为它的CSS样式而被滚动,所以我不得不通过将scroll绑定到$document来稍微调整代码:

( function () {

    'use strict';

    var angular = window.angular || {};

    angular
        .module( 'proverbial' )
        .directive( 'onDocumentScroll', Directive );

    Directive.$inject = ['$document'];

    function Directive( $document ) {

        var directive = {
            link: link,
            restrict: 'A'
        };

        return directive;

        function link( scope, element, attrs ) {
            $document.bind( 'scroll', function () {
                if ( $document.scrollTop() - scope.vm.latestThreshold >= element[0].offsetHeight ) {
                    scope.vm.latestThreshold += $document.scrollTop();
                    scope.$apply( attrs.onDocumentScroll );
                }
            } );
        }
    }
} )();

这解决了我的问题。