AngularJs Eliminar elementos duplicados en ng-repeat

Tengo un diccionario que está almacenado en field_detail

 
  • {{field.displayName}}
  • Ahora no quiero incluir duplicados displayName de field_detail , ¿qué filter debo usar?

    Simplemente cree un filtro que obtenga los valores únicos, probablemente con una clave. Algo como esto debería hacer (no probé esto en absoluto, así que te dejaré ese negocio, esto es solo para darte una 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; }; }); 
     

    Nota: Array.indexOf () no funciona en IE8 , por lo tanto, si está soportando IE8, necesitará colgar en indexOf (), o tendrá que usar un enfoque ligeramente diferente.

    Otros pensamientos: Probablemente sea mejor crear un filtro que aproveche la función única en lowdash o subrayado si ya hace referencia a esas bibliotecas.

    Desarrollé un JSFiddle basado en la respuesta proporcionada por Ben Leash:

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

    Gracias, Ben. Otras respuestas requerían el uso de AngularJS UI u otros marcos adicionales.

     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, } ]; }); 
    • {{ item.column }}

    Para aprovechar el uso de Ben Lesh, agregué la opción para eliminar objetos duplicados en una matriz si el nombre de clave es falso:

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

    Recibo un ticket que dice que cuando el usuario hace clic en guardar, recibe un error que dice Violación de restricción única, bla, bla … Quieren que mi pantalla les muestre duplicados antes de que la base de datos aplique la restricción. Así que escribí una función para recorrer todas las instancias de la matriz de objetos y contar las instancias de la misma.

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

    … y utilizo esta función en mi script para evitar el guardado, así:

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

    … y para mostrarle al usuario tan pronto como agreguen un nuevo registro, como este:

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

    … y luego en mi HTML tengo algo que decirle al usuario dónde está el duplicado …

        duplicate   ...  

    Sí, estoy comparando intencionalmente cada instancia consigo misma. Hay menos código de esa manera. Comprobo si .cnt> 1 en lugar de> 0.

    También para tomar nota de … el campo kpiList.cnt no existe hasta que la función se ejecuta por primera vez. El ng-show = “row.cnt> 1” indicará un falso (no es verdad) y no se mostrará hasta que row.cnt tenga un valor.

    Además, debe usar una Hoja de estilo para formatear su tramo en lugar de ponerlo en el atributo de estilo.

    Crea tu propia función:

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

    });