2013-11-22 18 views
5

Próbuję przenieść elementy, które są tworzone przez powtórzenie ng do niektórych kolumn. Udało mi się to z dyrektywą, ale problem pojawia się, kiedy sortuję tablicę obiektów, na których działa funkcja powtarzania ng. Dyrektywa, która wyszukuje najmniejszą kolumnę, a następnie wstawia do niej element, nie może określić najmniejszej kolumny (być może dlatego, że w kolumnach nadal znajdują się elementy). Wierzę, że struktura, której używam (dyrektywy/kontrolery itp. ...) nie jest optymalna i nie mogę znaleźć sposobu na uporządkowanie kodu, aby uzyskać pożądane zachowanie.Przenoszenie elementów kątowych JS utworzonych przez ng-repeat

Oto jsFiddle pokazujący, co mam teraz: http://jsfiddle.net/kytXy/6/ Możesz zobaczyć, że elementy są wstawiane poprawnie wewnątrz kolumn. Po kliknięciu przycisku, który ponownie porządkuje sortowanie, nie są one ponownie wstawiane. Jeśli klikniesz kilka razy na tym samym przycisku, obejrzyj, co się stanie ... Dodałem komentarze, które można odkomentować, dzięki czemu można zobaczyć, w jaki sposób wstawiane są elementy i co jest nie tak. Próbowałem również opróżnić kolumny przed ponownym wstawieniem (skomentował js w jsfiddle), bez żadnego sukcesu.

Oto kod: HTML:

<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script> 
<div ng-app="myModule"> 
    <div ng-controller="Ctrl" > 
     <button ng-click="predicate = 'id'; reverse=false; setupColumns()">Sort ID</button> 
     <button ng-click="predicate = 'id'; reverse=true; setupColumns()">Sort ID reversed</button> 
     <div id="columns" generate-sub-columns post-render> 
     </div> 
     <div class="elements"> 
      Elements are stored here ! 
     <div class="element" ng-repeat="(key,elt) in elts | orderBy:predicate:reverse" id="element{{key}}"> 
      Text: {{elt.a}} 
     </div> 
     </div> 
    </div> 
</div> 

JS:

var myModule = angular.module('myModule', []); 

myModule.controller('Ctrl', function($scope) { 
    $scope.predicate='id'; 
    $scope.reverse=false; 

    $scope.elts = [ 
     {id:0,a:"Hi man !"}, 
     {id:1,a:"This is some text"}, 
     {id:2,a:"Wanted to say hello."}, 
     {id:3,a:"Hello World!"}, 
     {id:4,a:"I love potatoes :)"}, 
     {id:5,a:"Don't know what to say now. Maybe I'll just put some long text"}, 
     {id:6,a:"Example"}, 
     {id:7,a:"Example2"}, 
     {id:8,a:"Example3"}, 
     {id:9,a:"Example4"}, 
     {id:10,a:"Example5"}, 
     {id:11,a:"Example6"} 
    ]; 

    $scope.setupColumns = function() { 
     console.log('calling setupColumns'); 
     var eltIndex = 0; 
     var element = jQuery("#element0"); 
     /*while(element.length > 0) { 
      jQuery('#elements').append(element); 
      eltIndex++; 
      element = jQuery("#element"+eltIndex); 
      alert(1); 
     } 
     alert('Columns should be empty');*/ 
     element = jQuery("#element0"); 
     eltIndex = 0; 
     var columnCount = 0; 
     while (jQuery("#column"+columnCount).size() >0) 
      columnCount++; 
     while(element.length > 0) { 
      console.log('placing new element'); 
      var smallestColumn = 0; 
      var smallestSize = jQuery("#columns").height(); 
      for (var i = 0; i < columnCount; i++) { 
       var columnSize = jQuery(".column#column"+i).height(); 
       if (columnSize < smallestSize) { 
        smallestColumn = i; 
        smallestSize = columnSize; 
       } 
      }; 
      jQuery('.column#column'+smallestColumn).append(element); 
      eltIndex++; 
      element = jQuery("#element"+eltIndex); 
      //alert(1); 
     } 
     //alert('Columns should be filled'); 
    }; 
}); 

myModule.directive('generateSubColumns', function() { 
    return { 
     restrict: 'A', 
     controller: function() { 
      var availableWidth = jQuery("#columns").width(); 
      var sizePerColumn = 100; 
      var nbColumns = Math.floor(availableWidth/sizePerColumn); 
      if (nbColumns<=1) 
       nbColumns=1; 
      for (var i = 0; i < nbColumns; i++) { 
       jQuery('<div class="column" id="column'+i+'">Column '+i+'</div>').appendTo('#columns'); 
      }; 
     } 
    }; 
}); 

myModule.directive('postRender', [ '$timeout', function($timeout) { 
    var def = { 
     restrict: 'A', 
     terminal: true, 
     transclude: true, 
     link: function(scope, element, attrs) { 
      $timeout(scope.setupColumns, 0); 
     } 
    }; 
    return def; 
}]); 

a niektóre css:

#columns { 
    width: 100%; 
} 

.column { 
    width: 100px; 
    display:inline-block; 
    vertical-align: top; 
    border: 1px solid black; 
} 

.element { 
    border: 1px solid red; 
} 

Jak mogę to naprawić? Z góry dziękuję, hilnius

Odpowiedz

0

Po pierwsze .. Dlaczego robisz coś takiego?

var element = jQuery("#element0"); 

Wewnątrz kontrolera? Ten rodzaj kodu (manipulacja DOM) powinien być zgodny z dyrektywą funkcji łącza i użyć parametru $element, aby uzyskać dostęp do elementu DOM.

Również .. Co zrobić, jeśli używasz własności column-count do podziału pojemnika? https://developer.mozilla.org/es/docs/Web/CSS/column-count