with portafolio por mostrar haciendo hacer filtros filtro filtrar filtrado elementos con como categorias busqueda bootstrap javascript filter group-by aurelia

javascript - portafolio - Cómo hacer un grupo por un filtro en Aurelia



portfolio filter html5 (3)

Estoy buscando la manera de hacer algo como

JS

$scope.players = [ {name: ''Gene'', team: ''alpha''}, {name: ''George'', team: ''beta''}, {name: ''Steve'', team: ''gamma''}, {name: ''Paula'', team: ''beta''}, {name: ''Scruath'', team: ''gamma''} ];

HTML:

<ul repeat.for="obj of players | groupBy: ''team''"> Group name: ${obj.group} <li repeat.for="player of obj.values"> player: ${player.name} </li> </ul>

Es posible de hacer? ¿O cuál es la mejor manera de hacer esta lógica en Aurelia?


Puedes hacer esto usando un ValueConverter .

export class GroupByValueConverter { toView(array, groupBy) { var groups = {}; array.forEach(function (o) { var group = o[groupBy]; groups[group] = groups[group] || []; groups[group].push(o); }); return Object.keys(groups).map(function (group) { return { group: group, values: groups[group] }; }) } }


Una extensión del ValueConverter anterior que permite usar un filtro de agrupación con propiedades de objetos anidados (por ejemplo, groupBy: ''team.id'')

export class GroupByValueConverter { toView(array, groupBy) { var groups = {}; var props = groupBy.split("."); array.forEach(function (o) { var group = o; props.forEach(function (p) { group = group[p] }); groups[group] = groups[group] || []; groups[group].push(o); }); return Object.keys(groups).map(function (group) { return { group: group, values: groups[group], }; }) } }

Aún otra extensión que permite especificar como grupo un objeto. Se necesita un segundo parámetro para especificar la clave del objeto que se utilizará como indexador.

p.ej. - | groupBy: ''equipo'': ''id'' - | groupBy: ''projectMember.team'': ''id''

export class GroupByValueConverter { toView(array, groupBy, groupByKey) { var groups = {}; var groupMembers = {}; var props = groupBy.split("."); array.forEach(function (o) { var group = o; props.forEach(function (p) { group = group[p] }); var index = groupByKey && group ? group[groupByKey] : group; groups[index] = group; groupMembers[index] = groupMembers[index] || []; groupMembers[index].push(o); }); return Object.keys(groups).map(function (index) { return { group: groups[index], values: groupMembers[index], }; }) } }


Después de encontrar esta respuesta, lo hice de una manera ligeramente diferente. En lugar de usar una matriz de objetos con claves de group y value , utilicé un Map .

Vista actualizada

<ul repeat.for="[group, values] of players | groupBy:''team''"> Group name: ${group} <li repeat.for="player of values"> player: ${player.name} </li> </ul>

Para el convertidor de valor, utilicé esta respuesta como inspiración en una forma eficiente de realizar un grupo por operación.

Convertidor de valor

export class GroupByValueConverter { toView(objects, key) { return objects.reduce( (rv, x) => rv.set(x[key], (rv.get(x[key]) || []).concat(x)), new Map() ); } }