2013-01-09 37 views
2

我想使用AngularJS指令實現自定義滾動窗格組件。在以下jsfiddle example我有一個基本原型的例子。AngularJS - 當指令呈現完成時如何查詢DOM

這裏是我的想法的一個模式: enter image description here

這裏是指令代碼:

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溢出隱藏和一個具有溢出滾動和另一個div來模仿拇指跟蹤器。

我的目標是監視scrollHeight屬性,然後相應地更改跟蹤器高度。問題是$ watch在DOM呈現之前被觸發,所以顯示和計算跟蹤器時會有延遲。現在,我在watch函數上使用了setTimeout,並且它工作正常(取消註釋行35和註釋34以查看它的行爲)。

什麼是正確的做法?

回答

5

is there a post render callback for Angular JS directive?

遺憾的是,沒有辦法確定渲染時是完整的(例如,沒有事件)。使用$超時似乎是可用的最佳解決方法。

在上面的鏈接中,@Nik在評論中提到他正在檢查$('tr').length > 3,以確定他的特定場景,以確定渲染何時完成。也許有些東西可以在DOM中定期檢查以確定渲染是否完成。

+0

謝謝你,我會研究它 –

4

兩個意見:

  • 你不需要compile恕我直言,但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個字,這裏有兩張截圖: last element still viewable gets inserted first element not viewable gets inserted

+0

感謝您的回覆,但正如您可以在更新的小提琴(http://jsfiddle.net/neuTA/136/)中看到的,它不能解決問題。您可以看到thumbTrack創建時延遲了一個$摘要步驟(等到內容在底部溢出) –

+0

從值溢出的那一刻開始出現藍色條。這不是應該如此? – asgoth

+0

你看過更新的小提琴嗎? (jsfiddle.net/neuTA/136)因爲這不是我所看到的,藍色條出現在第二行溢出 –

相關問題