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

app.controller('MainCtrl', function($scope, $timeout) {
  $scope.reset = function () {
    $scope.items = [{
      name: 'foo'
    }, {
      name: 'bar'
    }, {
      name: 'lorem'
    }, {
      name: 'ipsum'
    }];
  };
  
  $scope.reset();
  
  $scope.remove = function (item) {
    if (item.isRemoving) {
      return;
    }
    
    var previousPosition = $scope.items.indexOf(item),
      previousItem = $scope.items.splice(previousPosition, 1)[0];
    $timeout(function () {
      var ok = $scope.deactivateErrors || Math.random() > .5;
      if (!ok) {
        displayError('Cannot remove this item :(')
        $scope.items.splice(previousPosition, null, previousItem);
      }
    }, 2000)
  }
  
  var delay;
  function displayError (error) {
    $scope.error = 'Cannot remove this item :(';
    if (delay) {
      $timeout.cancel(delay);
    }
    delay = $timeout(function () {
      $scope.error = null;
    }, 2000);
  }
});
<!DOCTYPE html>
<html ng-app="plunker">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script data-require="angular.js@1.4.x" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.min.js" data-semver="1.4.6"></script>
    <script src="app.js"></script>
    <link href='https://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
  </head>

  <body ng-controller="MainCtrl">
    <p>Le faux backend a une chance sur deux de renvoyer une erreur.</p>
    <label><input type="checkbox" ng-model="deactivateErrors"> Désactiver les erreurs</label>
    <ul>
      <li
        ng-repeat="item in items"
        class="{{ item.isRemoving ? 'loading' : '' }}">
        {{ item.name }}
        <span
          class="remove"
          ng-click="remove(item)">X</span>
      </li>
    </ul>
    <p
      ng-if="error">{{ error }}</p>
    <button
      ng-click="reset()">Reset</button>
  </body>

</html>
body {
  font-family: 'open sans';
}
li {
  line-height: 48px;
  list-style: none;
  border-bottom: 1px solid #eee;
}
li:before {
  content: '';
  display: inline-block;
  width: 20px;
  height: 20px;
}
li.loading:before {
  background: url('oval.svg') no-repeat;
}
li .remove {
  float: right;
  cursor: pointer;
  color: red;
  font-family: sans-serif;
}

<!-- By Sam Herbert (@sherb), for everyone. More @ http://goo.gl/7AJzbL -->
<svg width="20" height="20" viewBox="0 0 38 38" xmlns="http://www.w3.org/2000/svg" stroke="#000">
    <g fill="none" fill-rule="evenodd">
        <g transform="translate(1 1)" stroke-width="2">
            <circle stroke-opacity=".5" cx="18" cy="18" r="18"/>
            <path d="M36 18c0-9.94-8.06-18-18-18">
                <animateTransform
                    attributeName="transform"
                    type="rotate"
                    from="0 18 18"
                    to="360 18 18"
                    dur="1s"
                    repeatCount="indefinite"/>
            </path>
        </g>
    </g>
</svg>