簡體   English   中英

綁定數據后,從指令操作DOM

[英]Manipulate DOM from directive after data is bound

我的目標是創建一個指令,將一組不同的高度div排列成一個模式,消除它們之間的空白。 就像Pinterest將divs鑲嵌成馬賽克一樣:

Pinterest截圖

我的方法是:

  1. 創建一個指令,將一組div包裝到tessellate。

     <tessellate columns="6"> <div ng-repeat="item in items" class="thumbnail"> {{item.name}} </div> </tessellate> 
  2. 使用指令模板首先設置列。 (tessellateTemplate.html)

     <div class="container"> <div class="row"> <div class="col-sm-{{12/columns}}" ng-repeat="i in numberToArray(columns) track by $index"></div> </div> </div> 
  3. 使用該指令在數據綁定到 div 抓取div 並逐個將它們添加到具有最短高度的列中。

     app.directive('tessellate', function () { return { restrict: 'E', scope: { columns: '=' }, controller: ['$scope', function ($scope) { // Ensure number of columns is divisible by 12. if (isNaN($scope.columns) || 12 % $scope.columns != 0) { $scope.columns = 6; } $scope.numberToArray = function (num) { return new Array(num); }; }], // Get child divs and add to template here. // Should I use compile or link?? templateUrl: "/app/directives/templates/tessellateTemplate.html" }; }); 

看起來很簡單吧? 我一直遇到的問題是我無法弄清楚如何在綁定數據獲取div。 這很重要,因為需要div的實際高度來決定它應該進入哪一列。

數據綁定后,有沒有辦法在指令中操作DOM?

要回答我自己的問題,我能解決這個問題的唯一方法是使用$ timeout。 我不是它的粉絲,但它有效。 如果有人有更好的方法,請發一個答案。 :)

我修改了我的指令模板(tessellateTemplate.html)來轉換div:

<div>
    <div class="container">
        <div class="row">
            <div class="col-sm-{{12/columns}}" ng-repeat="i in numberToArray(columns) track by $index"></div>
        </div>
    </div>
    <div ng-transclude></div>
</div>

然后我修改了我的指令以轉換transclude: true並且還在$ timeout中進行細分(請不要嘲笑我的鏈式方法調用,已經有一段時間了,因為我必須使用JQuery:P):

app.directive('tessellate', function () {
    return {
        restrict: 'E',
        replace: true,
        transclude: true,
        scope: {
            columns: '='
        },
        controller: ['$scope', '$element', '$attrs', function ($scope, $element, $attrs) {
            // Ensure number of columns is divisible by 12.
            if (isNaN($scope.columns) || 12 % $scope.columns != 0) {
                $scope.columns = 6;
            }

            $scope.numberToArray = function (num) {
                return new Array(num);
            };

            $scope.getShortestColumn = function () {
                var cols = $element.children().first().children().first().children();
                var shortCol = null;
                angular.forEach(cols, function (col) {
                    col = angular.element(col);
                    if (shortCol == null || col.height() < shortCol.height()) {
                        shortCol = col;
                    }
                });
                return shortCol;
            };

            $timeout(function () {
                var divs = $element.children().first().next().children();
                for (var i = 0; i < divs.length; i++) {
                    $scope.getShortestColumn().append(divs[i]);
                }
            }, 0);
        }],
        templateUrl: "/app/directives/templates/tessellateTemplate.html"
    };
});

用法保持不變:

<tessellate columns="6">
    <div ng-repeat="item in items">
        {{item.name}}
    </div>
</tessellate>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM