Подтвердить что ты не робот

AngularJs Удалите повторяющиеся элементы в ng-repeat

У меня есть один словарь, который хранится в field_detail

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

Теперь я не хочу включать дубликат displayName из field_detail, что filter использовать?

4b9b3361

Ответ 1

Просто создайте фильтр, который получит уникальные значения, возможно, с помощью ключа. Что-то вроде этого должно делать (я вообще этого не испытывал, поэтому я оставлю это дело вам, это только для того, чтобы дать вам представление):

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>

Примечание. Array.indexOf() не работает в IE8, поэтому, если вы поддерживаете IE8, вам нужно зайти в indexOf(), или вам нужно будет использовать немного другой подход.

Другие мысли. Вероятно, лучше всего создать фильтр, который использует уникальную функцию в lowdash или подчеркивании, если вы уже ссылаетесь на эти библиотеки.

Ответ 2

Я работал над JSFiddle на основе ответа, предоставленного Ben Leash:

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

Спасибо, Бен. Другие ответы требовали использования пользовательского интерфейса AngularJS или других таких дополнительных платформ.

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>

Ответ 3

Чтобы скомпоновать Ben Lesh, я добавил возможность удаления повторяющихся объектов в массиве, если ключевое слово ложно:

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;
};
});

Ответ 4

Я получаю билет, говорящий, когда пользователь щелкает их, они получают сообщение об ошибке Unique Constraint, blah blah.. Они хотят, чтобы мой экран отображал их дубликаты до того, как база данных будет принудительно использовать ограничение. Поэтому я написал функцию, чтобы перебрать все экземпляры массива объектов и подсчитать их экземпляры.

$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;
}

... и я использую эту функцию в своем script для предотвращения сохранения, например:

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

... и показать пользователю, как только они добавят новую запись, например:

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

... а затем в моем HTML мне есть что сказать пользователю, где дубликат...

<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>

Да, я намеренно сравниваю каждый экземпляр с самим собой. Там меньше кода. Я проверяю, есть ли .cnt > 1 вместо > 0.

Также обратите внимание на... поле kpiList.cnt не существует до тех пор, пока функция не будет запущена в первый раз. Ng-show = "row.cnt > 1" указывает ложное (не правдоподобное) и не будет отображаться до тех пор, пока значение row.cnt не будет иметь значения.

Кроме того, вы должны использовать StyleSheet для форматирования своего диапазона вместо того, чтобы помещать его в атрибут стиля.

Ответ 5

Создайте свою собственную функцию:

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

});