title: ng-repeat changing sort order on all items when new item added to model
body: <p>I created a "tessellate" directive that lets you wrap a number of divs.</p>
  
  <pre><code>&lt;tessellate columns="4"&gt;
    &lt;div class="thumbnail" ng-repeat="item in items track by item.id"&gt;
        {{item.Name}}&lt;br /&gt;
        {{item.Summary}}
    &lt;/div&gt;
  &lt;/tessellate&gt;
  </code></pre>
  
  <p>It takes one div at a time and appends it to the shortest of the specified number of columns to create a tessellation/mosaic effect. </p>
  
  <p>See the plunkr here: <a href="http://plnkr.co/edit/ur0bVCFRSz1UbRHeLjz8?p=preview" rel="nofollow">http://plnkr.co/edit/ur0bVCFRSz1UbRHeLjz8?p=preview</a></p>
  
  <p>The problem is that when the model changes, the ng-repeat uses the order that the divs appear <em>in the DOM</em> instead of the order in the model to redraw the elements. You can see that the items are sorted correctly at first and after clicking <code>Add</code> it is sorting the items from the first column horizontally, then the ones from the next column, etc.</p>
  
  <p><strong>How can I keep ng-repeat from using the DOM order to redraw elements?</strong> I already tried adding <code>orderBy item.id</code>, but it didn't help.</p>
  
  <pre><code>var app = angular.module('app', []);
  
  app.controller('itemController', ['$scope', function ($scope) {
      $scope.items = [
               { id:"1", Name:"Item1", Summary:"This is the summary of Item1" },
               { id:"2", Name:"Item2", Summary:"This is the summary of Item2. Some extra text on item two to test different heights." },
               { id:"3", Name:"Item3", Summary:"This is the summary of Item3" },
               { id:"4", Name:"Item4", Summary:"This is the summary of Item4. Some extra text on item four to test different heights." },
               { id:"5", Name:"Item5", Summary:"This is the summary of Item5. Some extra text on item five to test different heights. Some extra text on item to test different heights." },
               { id:"6", Name:"Item6", Summary:"This is the summary of Item6" },
               { id:"7", Name:"Item7", Summary:"This is the summary of Item7. Some extra text on item seven to test different heights." },
               { id:"8", Name:"Item8", Summary:"This is the summary of Item8" },
               { id:"9", Name:"Item9", Summary:"This is the summary of Item9. Some extra text on item nine to test different heights." },
               { id:"10", Name:"Item10", Summary:"This is the summary of Item10. Some extra text on item ten to test different heights." },
               { id:"11", Name:"Item11", Summary:"This is the summary of Item11" },
               { id:"12", Name:"Item12", Summary:"This is the summary of Item12. Some extra text on item to test different heights." },
               { id:"13", Name:"Item13", Summary:"This is the summary of Item13" },
               { id:"14", Name:"Item14", Summary:"This is the summary of Item14. Some extra text on item to test different heights." },
               { id:"15", Name:"Item15", Summary:"This is the summary of Item15. Some extra text on item to test different heights. Some extra text on item to test different heights." },
               { id:"16", Name:"Item16", Summary:"This is the summary of Item16" },
               { id:"17", Name:"Item17", Summary:"This is the summary of Item17. Some extra text on item to test different heights." },
               { id:"18", Name:"Item18", Summary:"This is the summary of Item18" }
               ];
      $scope.inc = $scope.items.length;
      $scope.add = function() {
          $scope.inc = $scope.inc + 1;
          $scope.items.push({ id: $scope.inc, Name: "New Item" + $scope.inc, Summary:"New Summary" });
      };
  }]);
  
  app.directive('tessellate', [function () {
      return {
          restrict: 'E',
          replace: true,
          transclude: true,
          scope: {
              columns: '='
          },
          controller: ['$scope', '$element', '$attrs', function ($scope, $element, $attrs) {
              $scope.numberToArray = function (num) {
                  return new Array(num);
              };
          }],
          link: function (scope, elem, attrs, ctrl) {
  
              scope.$watch(function () {
                  return elem.children().first().height();
              }, function (height) {
                  if (height &gt; 0) {
                      var containers = elem.children();
                      var transcludedDivsContainer = containers.first();
                      var targetColumns = containers.eq(1).children();
  
                      // Add the transcluded divs one at a time into the shortest column.
                      angular.forEach(transcludedDivsContainer.children(), function (div) {
                          var shortCol = null;
                          angular.forEach(targetColumns, function (col) {
                              col = angular.element(col);
                              if (shortCol === null || col.height() &lt; shortCol.height()) {
                                  shortCol = col;
                              }
                          });
                          shortCol.append(div);
                      });
                  }
              }
              );
          },
          templateUrl: "tessellateTemplate.html"
      };
  }]);
  </code></pre>