AngularJs Remove duplicate elements in ng-repeat

2019-01-07 09:26发布

I have one dictionary which is stored in field_detail

<li ng-repeat = "field in field_detail">{{field.displayName}}</li>

Now I dont want to include duplicate displayName of field_detail , what filter should I use?

5条回答
Root(大扎)
2楼-- · 2019-01-07 09:47

Just create a filter that gets the unique values, probably by a key. Something like this ought to do (I didn't test this at all, so I'll leave that business to you, this is just to give you an idea):

app.filter('unique', function() {
   return function(collection, keyname) {
      var output = [], 
          keys = [];

      angular.forEach(collection, function(item) {
          var key = item[keyname];
          if(keys.indexOf(key) === -1) {
              keys.push(key);
              output.push(item);
          }
      });

      return output;
   };
});
<div ng-repeat="item in items | unique: 'id'"></div>

Note: Array.indexOf() does not work in IE8, so if you're supporting IE8, you'll need to stub in indexOf(), or you'll need to use a slightly different approach.

Other thoughts: It's probably better just to create a filter that leverages the unique function in lowdash or underscore if you're already referencing those libraries.

查看更多
我只想做你的唯一
3楼-- · 2019-01-07 09:55

I get a ticket saying when the user clicks save they get an error saying Unique Constraint violation, blah blah.. They want my screen to show them duplicates before the database enforces the constraint. So I wrote a function to loop through all instances of the array of objects and count the instances of it.

$scope.anyDuplicates = function () {
    var dupes = false;
    for (var i = 0; i < $scope.kpiList.length; i++) {
        $scope.kpiList[i].cnt = 0;

        for (var j = 0; j < $scope.kpiList.length; j++) {

            if ($scope.kpiList[i].description == $scope.kpiList[j].description) {
                $scope.kpiList[i].cnt++;
            }

            if ($scope.kpiList[i].cnt > 1) dupes = true;
        }
    }
    return dupes;
}

...and I use this function in my script to prevent the save, like this:

if ($scope.anyDuplicates()) { 
   alert('Duplicates Detected.  Please remove the duplicates before pressing the save button.'); 
} else { 
   save();
}

...and to show the user as soon as they add a new record, like this:

$scope.kpiList.push({kpiId: newId, description: newDescription, new: true});
$scope.anyDuplicates();

... and then in my HTML I have something to tell the user where the duplicate is...

<tr ng-repeat="row in kpiList | filter:searchText | orderBy:['kpiTypeId', 'description'] ">
<td>
   <span 
      ng-show="row.cnt > 1" 
      style="color: red; font-size: xx-small">
      duplicate
   </span>
</td>
...
</tr>

Yes, I'm intentionally comparing each instance to itself. There's less code that way. I check to see if .cnt > 1 instead of > 0.

Also to take note of... the kpiList.cnt field doesn't exist until the function runs for the first time. The ng-show="row.cnt > 1" will indicate a false (not truthy) and will not display until row.cnt has a value.

Also, you should use a StyleSheet to format your span instead of putting it in the style attribute.

查看更多
Deceive 欺骗
4楼-- · 2019-01-07 10:01

Create your own function:

productArray =[];
angular.forEach($scope.leadDetail, function(value,key){
var index = $scope.productArray.indexOf(value.Product);
if(index === -1)
{
    $scope.productArray.push(value.Product);
}

});

查看更多
小情绪 Triste *
5楼-- · 2019-01-07 10:09

To piggyback off of Ben Lesh, I added the option to remove duplicate objects in an array if the keyname is falsy:

app.filter('unique', function () {
return function ( collection, keyname) {
    var output = [],
        keys = []
        found = [];

    if (!keyname) {

        angular.forEach(collection, function (row) {
            var is_found = false;
            angular.forEach(found, function (foundRow) {

                if (foundRow == row) {
                    is_found = true;                            
                }
            });

            if (is_found) { return; }
            found.push(row);
            output.push(row);

        });
    }
    else {

        angular.forEach(collection, function (row) {
            var item = row[keyname];
            if (item === null || item === undefined) return;
            if (keys.indexOf(item) === -1) {
                keys.push(item);
                output.push(row);
            }
        });
    }

    return output;
};
});
查看更多
够拽才男人
6楼-- · 2019-01-07 10:12

I worked up a JSFiddle based on the answer provided by Ben Leash:

http://jsfiddle.net/ThunderHemlock/bvsvzrr5/1/

Thanks, Ben. Other answers required the use of AngularJS UI or other such additional frameworks.

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

app.filter('unique', function() {
   return function(collection, keyname) {
      var output = [], 
          keys = [];

      angular.forEach(collection, function(item) {
          var key = item[keyname];
          if(keys.indexOf(key) === -1) {
              keys.push(key);
              output.push(item);
          }
      });
      return output;
   };
});

app.controller('MyCtrl', function ($scope) {

$scope.items = [
      {
        id : 1,
        column : "col1",
        comment : "col1-label1",
        text1 : "col1-label1-text1",
        checked: false,

      },
      {
        id : 2,
        column : "col1",
        comment : "col1-label2",
        text1 : "col1-label2-text1",
        checked: false,

      },
      {
        id : 3,
        column : "col2",
        comment : "col2-label1",
        text1 : "col2-label1-text1",
        checked: false,

      },
      {
        id : 4,
        column : "col2",
        comment : "col2-label2",
        text1 : "col2-label2-text1",
        checked: false,

      },
      {
        id : 5,
        column : "col3",
        comment : "col3-label1",
        text1 : "col3-label1-text1",
        checked: false,

      },
      {
        id : 6,
        column : "col3",
        comment : "col3-label2",
        text1 : "col3-label2-text1",
        checked: false,

      },
      {
        id : 7,
        column : "col4",
        comment : "col4-label1",
        text1 : "col4-label1-text1",
        checked: false,

      },
      {
        id : 8,
        column : "col4",
        comment : "col4-label2",
        text1 : "col4-label2-text1",
        checked: false,

      }
      ];
    });



<div ng-app="app">
        <div ng-controller="MyCtrl as item">
            <ul>
                <li ng-repeat="item in items | unique: 'column'">
                    {{ item.column }}
                </li>
            </ul>
        </div>
    </div>
查看更多
登录 后发表回答