Shmili Breuer
Shmili Breuer

Reputation: 4147

Reloading ng-repeat renders the new list before removing the old list

I need to measure the width of the UL that contains LI's with an ng-repeat the first time it works great. however when reloading the data the width comes in as double the real width I believe it is due to angular rendering the new LI's before removing the old LI's

How can I first remove the old LI's before rendering the new ones

P.S. If I put a timeout of 1000 it works fine however I don't wanna wait 1 second every time.

<ul class='ul'>
     <li ng-repeat="thing in data.things" class="buyer_li" ng-init="$last && getUlWidth()">
          <p>{{thing.detail}}
     </li>
</ul>
<button ng-click="reloadData()">Reload</button>



$scope.getUlWidth = function(){

    setTimeout(function() {
        $scope.ulWidth = document.querySelector('.ul').clientWidth;

    }, 0);
}

$scope.reloadData = function(){
     //reloadDataFunc;
}

Upvotes: 2

Views: 661

Answers (2)

Shmili Breuer
Shmili Breuer

Reputation: 4147

I found the reason why it happens It's because I didn't track the ng-repeat by anything, add =ing a track by $index solved the issue.

See this question and answers Angular ng-repeat causes flickering

Upvotes: 1

alphapilgrim
alphapilgrim

Reputation: 3975

I think it maybe your CSS for the layout, not exactly sure. But I'm including a pen that might be able to help.

function exampleController($scope, exampleFactory, $timeout) {
  $scope.list = [];
  $scope.listContainerWidth = '???';

  $scope.refreshList = function() {
    $scope.list = [];
    $scope.listContainerWidth = '???';
    $scope.listContainerWidth = document.querySelector('.ul').clientWidth;
    $timeout(function() {
      getList();
    }, 1000);
  };

  function getList() {
    exampleFactory
      .getList()
      .then(function(list) {
        $scope.list = list;
      });
  }

  getList();
}

function exampleFactory($http) {
  var root = 'http://jsonplaceholder.typicode.com';

  function getList() {
    return $http.get(root + '/comments')
      .then(function(resp) {
        return resp.data;
      });
  }
  return {
    getList: getList
  };
}

angular
  .module('app', [])
  .controller('exampleController', exampleController)
  .factory('exampleFactory', exampleFactory);
.container-fluid {
  background-color: #1D1F20;
  color: #fff;
  font-size: 14px;
  font-weight: bold;
  button {
    margin-top: 20%;
  }
}

ul li {
  list-style: none;
  margin: 10px;
}

.child-padding>div {
  padding: 2px;
}

.col-md-2 {
  position: fixed;
  button {
    margin-bottom: 10%;
  }
}

.circle-bound {
  float: left;
  text-align: center;
  border-radius: 50%;
  width: 25%;
  background-color: #0bf;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div class="container-fluid" ng-app="app">
  <div class="container" ng-controller="exampleController">
    <div class="row">
      <div class="col-md-2 text-center">
        <button class="btn btn-primary" type="button" ng-click="refreshList()">Refresh Comment List</button>
        <div class="circle-bound" ng-bind="listContainerWidth"></div>
      </div>
      <div class="col-md-10 pull-right">
        <ul class="ul">
          <li ng-repeat="comment in list track by $index">
            <div class="child-padding">
              <div ng-bind="comment.email"></div>
              <div ng-bind="comment.body"></div>
            </div>
            <div class="pull-right" ng-bind="comment.name"></div>
          </li>
        </ul>
      </div>
    </div>
  </div>
</div>

Upvotes: 0

Related Questions