You could scroll by the amount of the height of the added elements
$scope.addNewItem = function() {
    var wrapper = document.getElementsByClassName('wrapper')[0];
    $scope.items = $scope.items.concat({
      id: $scope.items.length,
      name: "item " + $scope.items.length
    });
    // will fail if you observe the item 0 because we scroll before the view is updated;
    wrapper.scrollTop+=101; //height+margings+paddings
  };
I am using a bad practice of accessing the DOM from the controller. A more modular approach would be to create a directive which will handle all cases and change the scroll position after the view is updated.
Demo at http://jsbin.com/zofofapo/8/edit
Alternatively, for the case where the items are not equally high, you could see how much scroll is left before the insertion, and re-set it after the insertion
$scope.addNewItem = function() {
    var wrapper = document.getElementsByClassName('wrapper')[0],
        scrollRemaining = wrapper.scrollHeight - wrapper.scrollTop;
    $scope.items = $scope.items.concat({
      id: $scope.items.length,
      name: "item " + $scope.items.length
    });
    // will fail if you observe the item 0 because we scroll before the view is updated;
    $timeout(function(){
      wrapper.scrollTop = wrapper.scrollHeight - scrollRemaining;
    },0);
  };
Demo at http://jsbin.com/zofofapo/9/edit