2014-05-19 24 views
3

我有一個具有ng-if屬性的div。在成功解析$http承諾後,相應的表達式將變爲真。在ng-if變爲true後訪問DOM元素

div包含ul,該ul又包含ling-repeat。列表項是根據$http調用返回的數據創建的。 ul有一個垂直滾動條。

在生成所有列表項後,我想要調整ul的高度,以便ul有一個滾動條,而窗口沒有。

我有一個功能來做到這一點。它在從窗口調整大小事件處理程序調用時起作用。我不知道如何在生成列表項後立即調用它。我怎樣才能做到這一點?

回答

1

我將創造一個指令:

.directive('adjustHeight', function ($timeout, $window) { 
    function adjustHeight(elem) { 
     // Do stuff - adjust the height 
    } 

    return { 
     restrict: 'A', 
     scope: { 
      data: '=' 
     }, 
     link: function postLink(scope, elem, attrs) { 
      var resizeListener = function (evt) { 
       adjustHeight(elem); 
      }; 

      /* Adjust height on window resize */ 
      $window.addEventListener('resize', resizeListener); 

      /* Adjust height when data changes 
      * (if necessary add an extra property for when being visible) */ 
      scope.$watchCollection('data', function (newValue, oldValue) { 
       if (newValue.length === oldValue.length) { 
        /* Maybe you don't need to re-adjust the height 
        * if the number of elements hasn't changed */ 
        return; 
       } 

       /* Wrapping the function inside a $timeout will ensure that 
       * the code is executed after the next browser rendering 
       * (thus after the modified list has been processed by ngRepeat) */ 
       $timeout(function() { adjustHeight(elem); }); 
      }); 

      /* Make sure to clear the window-resize listener, 
      * once the element is removed */ 
      scope.$on('$destroy', function() { 
       $window.removeEventListener('resize', resizeListener); 
      }); 
     } 
    }; 
}); 

然後,您可以使用它像這樣:

<div ng-if="someCondition" adjust-height data="items"> 
    <ul> 
     <li ng-repeat="item in items">{{item.property}}</li> 
    </ul> 
</div> 
+0

我打算建議一個指令。但是,除非該方法需要重用,否則指令可能是矯枉過正的。 – joseym

+0

@joseym:我不認爲如何(或在哪方面)這可能是一個矯枉過正的問題。除了可靠性之外,這裏的主要內容是功能封裝。如果它沒有包含在指令中,則應該在控制器中有代碼將一個事件附加到'window.onResize',其他代碼(可能在服務中),一旦數據被提取,將調整大小,更多內部控制器觀看用於當元素從頁面移除以便註銷聽衆時。 – gkalpak

+0

@joseym:這很糟糕,原因很多(現在看起來可能不是很糟糕,但是一旦你的應用開始增長......):1.控制器中的DOM /窗口操作。 2.代碼可能分散,不在一個地方。 3.不是聲明式的(通過查看視圖你不知道發生了什麼,你必須在控制器中搜索以找出發生了什麼)。 4.不可測試。 (我認爲這是Angular的**不是**的重要組成部分:)) – gkalpak

1

您可以將該函數傳遞給填充範圍的相同承諾,僅包含在$timeout中。

它看起來是這樣的:

$http.get('/someUrl').success(function(res){ 
    $scope.data = res; 
    $timeout(resizeFn); 
}); 
1

我與Angular2相同的問題:在* ngIf成爲true後,無法使用jQuery訪問元素。我的步行是:

setTimeout(() => { /* your code */ }, 0); 

該代碼將在DOM元素可用後執行。