简体   繁体   中英

Issue with <select ng-options=“…” />

I tried to achieve a simple feature with AngularJS as below. In item list, when user clicks an item and click the Remove button then the item will be removed.

在此输入图像描述

html:

<div ng-app="app" ng-controller="MainController">
    <div>
      <select ng-options="item.name for item in items" ng-model="currentItem" size="5" style="width: 200px"></select>
    </div>
    <button ng-click="removeItem()">Remove</button>
  </div>

and script is like below:

angular.module('app', [])
  .controller('MainController', function($scope) {
    $scope.items = [{
      name: 'item1'
    }, {
      name: 'item2'
    }, {
      name: 'item3'
    }];

    $scope.currentItem = $scope.items[0];

    $scope.removeItem = function() {
      var index = $scope.items.indexOf($scope.currentItem);
      $scope.items.splice(index, 1);
    };

  });

The problem is when I tried to remove an item (ie item2), the list always shows an empty item in the first position. When I click 'item1' or 'item3', the empty item disappears.

在此输入图像描述

I know that this is caused by ng-model="currentItem" in html. The item that currentItem points to get removed, currentItem points to null. So I changed the function removeItem as below to solve this issue.

$scope.removeItem = function() {
      var index = $scope.items.indexOf($scope.currentItem);
      $scope.items.splice(index, 1);

      /* PART 1 begin */
      if ($scope.items.length === 0) {
        $scope.currentItem = null;
      } else {
        if (index >= 0 && index <= $scope.items.length - 1) {
          $scope.currentItem = $scope.items[index];
        } else {
          $scope.currentItem = $scope.items[$scope.items.length - 1];
        }
      }
      /* PART 1 end */
    };

I would like to know whether there is any simple way (like a directive) in AngularJS to do the action in PART 1 automatically.

There is simple way in which you can prevent that is just include

 <option value="" ng-show="false"></option>

in select like as shown below

<select ng-options="item as item.name for item in items" ng-model="currentItem" size="5" style="width: 200px">
   <option value="" ng-show="false"></option>
</select>

Working Demo

UPDATE 1

I have resolved the issue of not highlighting the last item, Take a look the working demo

$scope.removeItem = function () {
    var index = $scope.items.indexOf($scope.currentItem);
    $scope.items.splice(index, 1);
    index === $scope.items.length ? $scope.currentItem = $scope.items[index - 1] : $scope.currentItem = $scope.items[index];
};

Working Demo

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM