【问题标题】:AngularJS - How to query the DOM when directive rendering is completeAngularJS - 指令渲染完成后如何查询 DOM
【发布时间】:2012-12-23 12:38:40
【问题描述】:

我正在尝试使用 AngularJS 指令实现自定义滚动窗格组件。在下面jsfiddle example我有一个基本原型的例子。

这是我的想法的架构:

这是指令代码:

    myApp.directive('lpScrollPane', function factory() {
    return {
        restrict: 'A',
        replace: true,
        transclude: true,
        template: '<div class="scrollPaneWrapper"><div class="scrollPane" ng-transclude></div><div class="thumbTrack" ></div></div>',
        compile: function (tElement, tAttrs) {
            var minHeight = 30;
            return function (scope, iElement, iAttrs) {
                var thumbTrack = angular.element(iElement.children()[1]);

                scope.onScrollHeight = function () {
                    console.log(iElement.children()[0].scrollHeight);

                    var H1 = iElement[0].offsetHeight;
                    var H2 = iElement.children()[0].scrollHeight;
                    if (H2 > H1) {
                        var trackHeight = Math.round(minHeight + (H1 - minHeight) * (1 - Math.pow((H2 - H1) / H2, 0.8)));
                        thumbTrack.css({
                            display: "block",
                            height: trackHeight + "px"
                        });
                        console.log(H2, H1, trackHeight);
                    } else {
                        thumbTrack.css({
                            display: "none"
                        });
                    }
                };

                scope.$watch(function () {
                    scope.onScrollHeight();
                    //setTimeout(scope.onScrollHeight, 100)
                });


            }
        }
    };
});

基本上有 2 次潜水,1 次隐藏溢出,1 次带有溢出滚动,另一个 div 模拟拇指跟踪器。

我的目标是监控 scrollHeight 属性,然后相应地更改跟踪器高度。问题是 $watch 在渲染 DOM 之前被触发,因此在显示和计算跟踪器时会出现延迟。现在我在 watch 函数上使用了 setTimeout,它工作正常(取消注释第 35 行和第 34 行以查看它的实际效果)。

正确的方法是什么?

【问题讨论】:

    标签: javascript web widget components angularjs


    【解决方案1】:

    is there a post render callback for Angular JS directive?

    很遗憾,无法确定渲染何时完成(例如,没有事件)。使用 $timeout 似乎是最好的解决方法。

    在上面的链接中,@Nik 在评论中提到他正在检查$('tr').length &gt; 3,以针对他的特定场景来确定渲染何时完成。也许您可以定期检查 DOM 中的某些内容以确定渲染是否完成。

    【讨论】:

    • 谢谢,我会调查的
    【解决方案2】:

    两个观察结果:

    • 你不需要compile imho,而是link 函数
    • 你应该等到元素准备好,而不是使用超时

    所以:

    myApp.directive('lpScrollPane', function factory() {
      return {
        restrict: 'A',
        replace: true,
        transclude: true,
        template: '<div class="scrollPaneWrapper"><div class="scrollPane" ng-transclude></div><div class="thumbTrack" ></div></div>',
        link: function (scope, iElement, iAttrs) {
          var minHeight = 30;
          var thumbTrack = angular.element(iElement.children()[1]);
    
          scope.onScrollHeight = function () {
            console.log(iElement.children()[0].scrollHeight);
    
            var H1 = iElement[0].offsetHeight;
            var H2 = iElement.children()[0].scrollHeight;
            if (H2 > H1) {
              var trackHeight = Math.round(minHeight + (H1 - minHeight) * (1 - Math.pow((H2 - H1) / H2, 0.8)));
              thumbTrack.css({
                display: "block",
                height: trackHeight + "px"
              });
              console.log(H2, H1, trackHeight);
            } else {
              thumbTrack.css({
                display: "none"
              });
            }
          };
    
          iElement.ready(function () {  
             scope.$watch(function () {
               scope.onScrollHeight();
             });
          });        
        }
      };
    });
    

    jsFiddle

    编辑:

    因为2张图片超过1000字,这里有两张截图:

    【讨论】:

    • 感谢您的回复,但正如您在更新的小提琴 (jsfiddle.net/neuTA/136) 中看到的那样,它并没有解决问题。可以看到thumbTrack的创建延迟了一个$digest step(等到底部内容溢出)
    • 蓝条从值溢出的那一刻开始出现。这不是应该的样子吗?
    • 你看过更新的小提琴了吗? (jsfiddle.net/neuTA/136) 因为我看到的不是这个,所以蓝条出现在第二行overflow
    • 你的意思是开头的(半)蓝条出现半秒吗?
    • 不,这只是一个 CSS 问题(已修复 jsfiddle.net/neuTA/139),我看到正常的溢出滚动,然后当插入另一行时出现蓝条(我使用 chrome)
    猜你喜欢
    • 2017-10-30
    • 2012-08-27
    • 1970-01-01
    • 1970-01-01
    • 2013-06-14
    • 2023-03-24
    • 2015-06-16
    • 2023-03-17
    • 2016-12-23
    相关资源
    最近更新 更多