Angular ng通过ng选项重复多个选择字段,而不显示已选择的数据

Angular ngRepeat multiple select fields without displaying already selected data through ng-options

本文关键字:ng 选择 显示 数据 字段 选项 Angular 通过      更新时间:2023-09-26

所以问题的概述;我正在从一个api中检索数据,并为它创建一个CRUD页面。数据有一组标签,用户可以选择。

下面是一个代表我的问题的代码示例。用户选择的标签由user.labels关系表示,并且可以选择的可用标签总数由user.parent.grandparent.labels表示。

我可以同步所选内容。我似乎不知道如何从任何其他后续选择字段的选项列表中删除已经选择的选项。

angular.module('app', [])
  .controller('select', ['$scope', '$filter', '$location',
    function($scope, $filter, $location) {
      $scope.user = {
        "parent": {
          "grandparent": {
            "labels": [{
              "id": 28,
              "name": "Label 1",
            }, {
              "id": 17,
              "name": "Label 2",
            }, {
              "id": 39,
              "name": "Label 3",
            }, {
              "id": 77,
              "name": "Label 4"
            }, {
              "id": 100,
              "name": "Label 5"
            }]
          }
        },
        "labels": [{
          "id": 28,
          "name": "Label 1",
          "meta": {
            "score": 3
          }
        }, {
          "id": 17,
          "name": "Label 2",
          "meta": {
            "score": 5
          }
        }]
      };
    }
  ]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="select">
  <div ng-repeat="label in user.labels track by $index">
    <div class="form-field">
      <span>Label</span>
      <select ng-model="user.labels[$index]" ng-options="department.name for department 
                        in user.parent.grandparent.labels track by department.id">
      </select>
    </div>
    <div>
      <span>Score</span>
      <select ng-model="label.meta.score">
        <option value="1">1 (lowest)</option>
        <option value="2">2</option>
        <option value="3">3</option>
        <option value="4">4</option>
        <option value="5">5 (highest)</option>
      </select>
    </div>
  </div>
  <button ng-click="user.labels.push({})">Add Label</button>
</div>

您可以在ng repeat中使用过滤函数来实现这一点,这里有一个示例Codepen向您展示了如何:

http://codepen.io/anon/pen/ZYveOo

您需要通过重复定义中的过滤器:

<select ng-model="user.labels[$index]" ng-options="department.name for department in user.parent.grandparent.labels | filter:removeSelected track by department.id ">

指的是范围上的此功能:

      $scope.removeSelected = function(val){
        return !_.find($scope.user.labels, function(label) {
          return label.id === val.id;
        });
      };

尽管我认为您缺少一个用例,即您希望能够将当前选定的标签包含在选项中,但通过删除所有选定的选项,您就是在删除该功能。

更新:

好吧,那么,在考虑了这个问题之后,我想出了以下过滤器,它可以进行优化,但似乎确实如预期的那样工作:

.filter('duplicatesFilter', function() {
        return function(items, index, selected) { 
          var res = [selected[index]];
          _.forEach(items, function(item){
            if(!_.find(selected, function(label) {
              return label.id === item.id;
            })){
              res.push(item);
            }
          });
          return res;
        };
    })

像这样使用:

<select ng-model="user.labels[$index]" ng-options="department.name for department in user.parent.grandparent.labels | duplicatesFilter:$index:user.labels track by department.id "></select>

这是我遇到过几次的问题,每次我都会解决它。如果我能找到一个更好地解决问题的自定义过滤器,我稍后会看一看,如果我不能,我会整理这个代码并发布一个;然而,这对于您的用例来说应该是很好的。

工作代码笔:

http://codepen.io/anon/pen/ZYveOo