我有一个通过ng-repeat创建的数组的输入列表。我想检查它们中是否有重复的值。如果发现任何重复的值,则会显示一条错误消息。
我在JS FIDDLE中找到了想要的东西

<tr ng-repeat="person in persons">
            <td>
                <ng-form name="personForm">
                 <div ng-class="{ 'has-error' :
                    personForm.personName.$invalid }">
                    <input type='text'
                    name="personName"
                    ng-class="empty"
                    ng-model="person.name"
                    ng-change="verifyDuplicate()"/>
                   </div>
                 </ng-form>
                <div class='error'
                    ng-if='person.isDuplicate'>
                    Duplicate.
                </div>
            </td>


            

$scope.verifyDuplicate = function() {
        var sorted, i;

        sorted = $scope.persons.concat().sort(function (a, b) {
            if (a.name > b.name) return 1;
            if (a.name < b.name) return -1;
            return 0;
        });
        for(i = 0; i < $scope.persons.length; i++) {
            sorted[i].isDuplicate = ((sorted[i-1] && sorted[i-1].name == sorted[i].name) || (sorted[i+1] && sorted[i+1].name == sorted[i].name));
        }
    };


所以我在Plunker中实现了这一点

<div ng-repeat="item in csTagGrp">
    <div ng-repeat="person in item.csTags">
      <ng-form name="personForm">
        <div ng-class="{ 'has-error' :
                    personForm.personName.$invalid }">
          <input type='text' name="personName" ng-class="empty" ng-model="person.keys" ng-change="verifyDuplicate()" />
        </div>
      </ng-form>
      <div class='error' ng-if='person.isDuplicate'>
        Duplicate.
      </div>
    </div>
  </div>


$scope.verifyDuplicate = function() {
    var sorted, i;

    sorted = $scope.csTagGrp.csTags.concat().sort(function(a, b) {
      if (a.name > b.name) return 1;
      if (a.name < b.name) return -1;
      return 0;
    });
    for (i = 0; i < $scope.csTagGrp.csTags.length; i++) {
      sorted[i].isDuplicate = ((sorted[i - 1] && sorted[i - 1].name == sorted[i].name) || (sorted[i + 1] && sorted[i + 1].name == sorted[i].name));
    }
  };


但是由于某种原因,它似乎无法正常工作。我在这里使用不同的嵌套对象数组。我在这里做错了什么?

提前致谢。

最佳答案

它不起作用,因为您在sort函数中使用了错误的键名,并且您正在尝试使用嵌套对象。

只需对其进行修改,即可使其与数组中的第一个对象一起使用。您将需要遍历每个对象,以使其对所有对象均有效。

$scope.verifyDuplicate = function() {
    var sorted, i;

    sorted = $scope.csTagGrp[0].csTags.concat().sort(function(a, b) {
      if (a.keys > b.keys) return 1;
      if (a.keys < b.keys) return -1;
      return 0;
    });
    for (i = 0; i < $scope.csTagGrp[0].csTags.length; i++) {
      sorted[i].isDuplicate = ((sorted[i - 1] && sorted[i - 1].keys == sorted[i].keys) || (sorted[i + 1] && sorted[i + 1].keys == sorted[i].keys));
    }
  };


因为您使用的是嵌套对象,所以这成为要解决的稍微复杂的问题。您有一个对象数组,其中也包含数组。如果(可以)将所有内容放到扁平的对象中,则很简单。

csTagGrp[0]告诉它访问csTagGrp数组中的第一个对象,即:

{
    "csTagTitle": "Action",
    "csTags": [{
      "keys": "1",
      "tags": "Quick Win"
    }, {
      "keys": "2",
      "tags": "follow up with respondent"
    }, {
      "keys": "3",
      "tags": "process imporvement"
    }, {
      "keys": "4",
      "tags": "Large Fix"
    }, {
      "keys": "5",
      "tags": "use in presentation"
    }]
  }


因此,现在sorted访问csTagGrp数组中对象[0]处的csTags数组,并对该数组中的所有keys进行排序。到现在为止还挺好。但是,有了这里的对象结构,您需要遍历两个数组(即,csTagGrp中的所有对象以及每个csTagGrp对象中的每个csTags数组)并对其全部执行排序。这通常涉及多个for循环。

因此,要完成此操作,我将所有csTags数组(使用for循环)连接到一个新数组preSort中,然后将其传递给进行排序。这提供了我们需要的内容(一个平面数组)来检查所有csTags数组是否重复。

  $scope.verifyDuplicate = function() {
    var preSort = [],sorted, i, c = $scope.csTagGrp;

    for(i = 0; i < c.length; i++) {
      preSort = preSort.concat(c[i].csTags);
    }

    sorted = preSort.concat().sort(function(a, b) {
      if (a.keys > b.keys) return 1;
      if (a.keys < b.keys) return -1;
      return 0;
    });
    console.log(sorted)
    for (i = 0; i < preSort.length; i++) {
      sorted[i].isDuplicate = ((sorted[i - 1] && sorted[i - 1].keys == sorted[i].keys) || (sorted[i + 1] && sorted[i + 1].keys == sorted[i].keys));
    }
  };
});


Here is the working demo.

08-25 11:51