Angular Agrupar cuadrícula por

    Un comportamiento Agrupar por de una tabla de Ignite UI for Angular o cuadrícula de interfaz de usuario crea filas de datos agrupadas en función de los valores de las columnas. El Group By in igxGrid permite visualizar los grupos en una estructura jerárquica. Las filas de datos agrupadas se pueden expandir o contraer, y el orden de agrupación se puede cambiar a través de la interfaz de usuario o la API. Cuando la selección de filas está habilitada, se representa un selector de filas Agrupar por en el área más a la izquierda de la fila de grupo. En caso de que la propiedad se establezca en single, las rowSelection casillas de verificación están deshabilitadas y solo sirven como indicación para el grupo donde se coloca la selección. Si la rowSelection propiedad se establece en múltiples, al hacer clic sobre el selector de filas Agrupar por, se seleccionan todos los registros que pertenecen a este grupo.

    Angular Grupo de cuadrícula por ejemplo

    Este ejemplo presenta las capacidades de agrupación de una gran cantidad de datos. Arrastrar los encabezados de las columnas a la parte superior (área de agrupación) permite a los usuarios ver los datos de la columna seleccionada en una estructura jerárquica. Pueden agrupar en varios campos arrastrando más encabezados de columna a la parte superior. Estas opciones de agrupación resultan útiles cuando tienes tablas con numerosas filas y columnas donde los usuarios quieren presentar los datos de una manera mucho más rápida y visualmente aceptable.

    EXAMPLE

    ¿Te gusta esta muestra? Obtenga acceso a nuestro kit de herramientas de Ignite UI for Angular completo y comience a crear sus propias aplicaciones en minutos. Descárgalo gratis.

    Estado de agrupación inicial

    Es posible definir la agrupación inicial de la cuadrícula asignando una matriz de expresiones a la propiedad groupingExpressions de la cuadrícula.

    public ngOnInit() {
        grid.groupingExpressions = [
            { fieldName: 'ProductName', dir: SortingDirection.Desc },
            { fieldName: 'Released', dir: SortingDirection.Desc }
        ];
    }
    typescript

    Las expresiones de agrupación implementan la interfaz ISortingExpression.

    Agrupar por API

    API de agrupación

    La agrupación está disponible a través de la interfaz de usuario y mediante una API sólida expuesta por el componente de cuadrícula. Los desarrolladores pueden permitir a los usuarios finales agrupar los datos de la cuadrícula por ciertas columnas, estableciendo la propiedad groupable de cada columna en true.

    <igx-grid [data]="data">
        <igx-column *ngFor="let c of columns" [field]="c.field" [groupable]="true">
        </igx-column>
    </igx-grid>
    html
    public ngOnInit() {
        grid.columns.forEach((column) => {
            column.groupable = true;
        });
    }
    typescript

    Durante el tiempo de ejecución, las expresiones se pueden obtener y configurar desde la propiedad groupingExpressions. Si necesita agregar o cambiar una expresión existente, también puede usar el método groupBy con una única o una matriz de ISortingExpression.

    grid.groupBy({ fieldName: 'ProductName', dir: SortingDirection.Desc, ignoreCase: true });
    typescript

    Hasta ahora, la agrupación/clasificación funcionaba en conjunto. En la versión 13.2, se introduce un nuevo comportamiento que desacopla la agrupación de la ordenación. Por ejemplo, al borrar la agrupación, no se borrarán las expresiones de ordenación en la cuadrícula o viceversa. Aun así, si una columna está ordenada y agrupada, las expresiones agrupadas tienen prioridad.

    Expandir/contraer API

    Además de agrupar expresiones, también puede controlar los estados de expansión de las filas del grupo. Se almacenan en una propiedad separada del componente igxGrid​ ​groupingExpansionState. Una fila de grupo se identifica de forma única según el nombre del campo para el que se crea y el valor que representa para cada nivel de agrupación. Esto significa que la firma de una interfaz de estado de expansión es la siguiente:

    export interface IGroupByKey {
        fieldName: string;
        value: any;
    }
    
    export interface IGroupByExpandState {
        hierarchy: Array<IGroupByKey>;
        expanded: boolean;
    }
    typescript

    Al igual que con groupingExpressions, configurar una lista de IGroupByExpandState directamente en groupingExpansionState cambiará la expansión en consecuencia. Además, igxGrid expone un método que alterna un grupo según la instancia de registro del grupo.

        const groupRow = this.grid.groupsRecords.find(r => r.value === "France");
        const groupRow = this.grid.getRowByIndex(0).groupRow;
        grid.toggleGroup(groupRow);
        groupRow.expanded = false;
    typescript

    Los grupos se pueden crear expandidos (predeterminado) o contraídos y los estados de expansión generalmente solo contendrán el estado opuesto al comportamiento predeterminado. Puede controlar si los grupos deben crearse expandidos o no a través de la propiedad groupsExpanded.

    Seleccionar/deseleccionar todas las filas en una API de grupo

    Seleccionar/deseleccionar todas las filas de un grupo está disponible a través de los métodos API selectRowsInGroup y deselectRowsInGroup.

    El siguiente fragmento de código se puede utilizar para seleccionar todas las filas dentro de un grupo utilizando el método selectRowsInGroup de instancia de registro de grupo. Además, el segundo parámetro de este método es una propiedad booleana mediante la cual puede elegir si la selección de fila anterior se borrará o no. La selección anterior se conserva de forma predeterminada.

        const groupRow = this.grid.groupsRecords.find(r => r.value === "France");
        const groupRow = this.grid.getRowByIndex(0).groupRow;
        grid.selectRowsInGroup(groupRow);
    typescript

    Si necesita anular la selección de todas las filas dentro de un grupo mediante programación, puede utilizar el método deselectRowsInGroup.

        const groupRow = this.grid.groupsRecords.find(r => r.value === "France");
        const groupRow = this.grid.getRowByIndex(0).groupRow;
        grid.deselectRowsInGroup(groupRow);
    typescript

    Plantillas

    Plantillas de filas de grupo

    La fila del grupo, excepto la interfaz de usuario para expandir/contraer, es totalmente adaptable a plantillas. De forma predeterminada, muestra un icono de agrupación y muestra el nombre del campo y el valor que representa. La plantilla de registro de agrupación con la que se presenta tiene la siguiente firma:

    export interface IGroupByRecord {
        expression: ISortingExpression;
        level: number;
        records: GroupedRecords;
        value: any;
        groupParent: IGroupByRecord;
        groups?: IGroupByRecord[];
    }
    typescript

    Como ejemplo, la siguiente plantilla haría que el resumen de filas del grupo fuera más detallado:

    <ng-template igxGroupByRow let-groupRow>
        <span>Total items with value: {{ groupRow.value }} are {{ groupRow.records.length }}</span>
    </ng-template>
    html

    Plantillas de selector de filas de grupo

    Como se mencionó anteriormente, la fila del grupo, excepto la interfaz de usuario para expandir/contraer, es totalmente adaptable a plantillas. Para crear una plantilla de selector de filas Agrupar por personalizada dentro de la cuadrícula, declare una <ng-template> con la directiva igxGroupByRowSelector. Desde la plantilla, puede acceder a la variable de contexto proporcionada implícitamente, con propiedades que le brindan información sobre el estado de la fila Agrupar por.

    La propiedad selectedCount muestra cuántos registros del grupo están seleccionados actualmente, mientras que totalCount muestra cuántos registros pertenecen al grupo.

    <ng-template igxGroupByRowSelector let-groupByRowContext>
        {{ groupByRowContext.selectedCount }} / {{ groupByRowContext.totalCount  }}
    </ng-template>
    html

    La propiedad groupRow devuelve una referencia a la fila del grupo.

    <ng-template igxGroupByRowSelector let-groupByRowContext>
        <div (click)="handleGroupByRowSelectorClick($event, groupByRowContext.groupRow)">Handle groupRow</div>
    </ng-template>
    html

    Las propiedades selectedCount y totalCount se pueden utilizar para determinar si el selector de fila Agrupar por debe estar marcado o indeterminado (seleccionado parcialmente).

    <igx-grid #grid [data]="gridData" primaryKey="ProductID" rowSelection="multiple">
        <!-- ... -->
        <ng-template igxGroupByRowSelector let-context>
            <igx-checkbox
                [checked]=" context.selectedCount > 0 && context.selectedCount === context.totalCount"
                [indeterminate]="context.selectedCount > 0 && context.selectedCount !== context.totalCount">
            </igx-checkbox>
        </ng-template>
    </igx-grid>
    html
    App Builder | CTA Banner

    Angular Agrupar cuadrículas por con paginación

    Las filas de grupo participan en el proceso de paginación junto con las filas de datos. Cuentan para el tamaño de página de cada página. Las filas contraídas no se incluyen en el proceso de paginación. Cualquier operación de expandir o contraer obliga a Paging a recalcular el recuento de páginas y ajustar el índice de páginas si es necesario. Los grupos que abarcan varias páginas se dividen entre ellos. La fila del grupo es visible solo en la página en la que comienza y no se repite en las páginas siguientes. La información de resumen de las filas del grupo se calcula en función de todo el grupo y no se ve afectada por la paginación.

    Ejemplo de agrupación de Angular con paginación

    EXAMPLE

    Agrupar por con resúmenes

    La integración entre Agrupar por y Resúmenes se describe en el tema Resúmenes.

    Navegación por teclado

    La interfaz de usuario de agrupación admite las siguientes interacciones de teclado:

    • Para filas de grupo (el foco debe estar en la fila o en la celda expandir/contraer)

      • ALT + DERECHA: expande el grupo
      • ALT + IZQUIERDA: colapsa el grupo
      • ESPACIO: selecciona todas las filas del grupo, si la propiedad RowSelection está establecida en múltiples
    • Para los componentes del grupo igxChip en el área de grupo (el foco debe estar en el chip)

      • MAYÚS + IZQUIERDA: mueve el chip enfocado hacia la izquierda, cambiando el orden de agrupación, si es posible
      • MAYÚS + DERECHA: mueve el chip enfocado hacia la derecha, cambiando el orden de agrupación, si es posible
      • ESPACIO: cambia la dirección de clasificación
      • ELIMINAR: desagrupa el campo
      • Los elementos separados del chip también se pueden enfocar y se puede interactuar con ellos mediante la ENTER llave.

    Angular Cuadrícula personalizada Agrupar por

    igxGrid permite definir agrupaciones personalizadas por columna o por expresión de agrupación, lo que proporciona agrupaciones basadas en una condición personalizada. Esto es útil cuando necesita agrupar por objetos complejos o para otros escenarios específicos de aplicaciones.

    Para implementar una agrupación personalizada, los datos primero deben ordenarse adecuadamente. Debido a esto, es posible que también necesite aplicar una estrategia de clasificación personalizada que amplíe la base DefaultSortingStrategy. Una vez ordenados los datos, los grupos personalizados se pueden determinar especificando un groupingComparer para la columna o para la expresión de agrupación específica.

    El siguiente ejemplo muestra la agrupación personalizada por Date, donde los valores de fecha se ordenan y agrupan por Día, Semana, Mes o Año según el modo de agrupación seleccionado por el usuario.

    Angular grupo personalizado por ejemplo

    EXAMPLE

    El ejemplo define estrategias de clasificación personalizadas para las diferentes condiciones de fecha. Cada estrategia personalizada amplía la base DefaultSortingStrategy y define el método compareValues, que es la función de comparación personalizada que se utiliza al ordenar los valores. Además extrae los valores de la fecha necesarios para la comparación.

    class BaseSortingStrategy extends DefaultSortingStrategy {
    
        public getParsedDate(date: any) {
            return {
                day: date.getDay(),
                month: date.getMonth() + 1,
                year: date.getFullYear()
            };
        }
    
        compareValues(a: any, b: any) {
            const dateA = this.getParsedDate(a);
            const dateB = this.getParsedDate(b);
            return dateA.year < dateB.year ?
                -1 : dateA.year > dateB.year ?
                1 : dateA.month  < dateB.month ?
                -1 : dateA.month > dateB.month ?
                1 : 0;
        }
    }
    
    class DaySortingStrategy extends BaseSortingStrategy {
        compareValues(a: any, b: any) {
            const dateA = this.getParsedDate(a);
            const dateB = this.getParsedDate(b);
            return dateA.year < dateB.year ?
                -1 : dateA.year > dateB.year ?
                1 : dateA.month  < dateB.month ?
                -1 : dateA.month > dateB.month ?
                1 : dateA.day < dateB.day ?
                -1 : dateA.day > dateB.day ?
                1 : 0;
        }
    }
    
    class WeekSortingStrategy extends BaseSortingStrategy {
    
        public getWeekOfDate(a: any) {
           return parseInt(new DatePipe("en-US").transform(a, 'w'), 10);
        }
    
        compareValues(a: any, b: any) {
            const dateA = this.getParsedDate(a);
            const dateB = this.getParsedDate(b);
            const weekA = this.getWeekOfDate(a);
            const weekB = this.getWeekOfDate(b);
            return dateA.year < dateB.year ?
                -1 : dateA.year > dateB.year ?
                1 : weekA < weekB ?
                -1 : weekA > weekB ?
                1 : 0;
        }
    }
    typescript

    Se define una función groupingComparer para las expresiones de agrupación, que determina los elementos que pertenecen al mismo grupo en función del modo de agrupación seleccionado. Los valores de los datos ordenados para los que esta función devuelve 0 se marcan como parte del mismo grupo.

     groupingComparer: (a, b) => {
        const dateA = this.sortingStrategy.getParsedDate(a);
        const dateB = this.sortingStrategy.getParsedDate(b);
        if (this.groupByMode === 'Month') {
            return dateA.month === dateB.month ? 0 : -1;
        } else if (this.groupByMode === "Year") {
            return dateA.year === dateB.year ? 0 : -1;
        } else if (this.groupByMode === "Week") {
            return this.sortingStrategy.getWeekOfDate(a) === this.sortingStrategy.getWeekOfDate(b) ? 0 : -1;
        }
        return dateA.day === dateB.day && dateA.month === dateB.month ? 0 : -1;
    }
    typescript

    A partir de la versión 15.1.0, también puede utilizar la estrategia de clasificación integrada GroupMemberCountSortingStrategy para ordenar elementos según el recuento de miembros.

    public sortByGroup() {
            const expressions = this.grid1.groupingExpressions;
            if (expressions.length) {
                const fieldName = expressions[0].fieldName;
                const dir = expressions[0].dir === SortingDirection.Asc ? SortingDirection.Desc : SortingDirection.Asc;
                this.grid1.groupBy({ fieldName, dir, ignoreCase: false, strategy: GroupMemberCountSortingStrategy.instance() });
            }
        }
    typescript

    Estilo

    El igxGrid permite estilizar a través de Ignite UI for Angular Theme Library. La cuadrícula grid-theme expone una amplia variedad de propiedades, que permiten la personalización de todas las características de la cuadrícula.

    En los pasos siguientes, veremos los pasos para personalizar el estilo Agrupar por de la cuadrícula.

    Importando tema global

    Para comenzar la personalización de la función Agrupar por, debe importar el archivo index, donde se encuentran todas las funciones de estilo y mixins.

    @use "igniteui-angular/theming" as *;
    
    // IMPORTANT: Prior to Ignite UI for Angular version 13 use:
    // @import '~igniteui-angular/lib/core/styles/themes/index';
    scss

    Definición de tema personalizado

    A continuación, cree un nuevo tema, que extienda el grid-theme y acepte los parámetros necesarios para personalizar Agrupar por como desee. También es necesario ampliar el chip-theme, porque se utiliza en la función Agrupar por.

    
    $custom-theme: grid-theme(
      $group-row-background: #494949,
      $group-row-selected-background: #383838,
      $group-label-column-name-text: #f8f8f8,
      $group-label-icon: #ffcd0f,
      $group-label-text: #f8f8f8,
      $group-count-background: #ffcd0f,
      $group-count-text-color: #000,
      $expand-icon-color: #ffcd0f,
      $expand-icon-hover-color: rgb(223, 181, 13),
      $cell-active-border-color: #ffcd0f,
      $row-selected-background: #fff6d3,
      $row-selected-text-color: #000,
      $drop-indicator-color: #ffcd0f
    );
    
    /* Chip theme will style the chips in the Group By area */
    $custom-chips-theme: chip-theme(
      $background: #494949,
      $text-color: #f8f8f8,
      $hover-text-color: #e7e7e7
    );
    scss

    Definir una paleta de colores personalizada

    En el enfoque que describimos anteriormente, los valores de color se codificaron de forma rígida. Alternativamente, puede lograr una mayor flexibilidad, utilizando las palette funciones y color.
    palette Genera una paleta de colores, basada en los colores primarios, secundarios y de superficie proporcionados.

    $black-color: #292826;
    $yellow-color: #ffcd0f;
    $grey-color: #efefef;
    
    $custom-palette: palette(
      $primary: $black-color, 
      $secondary: $yellow-color, 
      $surface: $grey-color
    );
    scss

    Una vez que se ha generado una paleta personalizada, la color función se puede utilizar para obtener diferentes variedades de los colores primarios y secundarios.

    $custom-theme: grid-theme(
      $group-row-background: color($custom-palette, "primary", 300),
      $group-row-selected-background: color($custom-palette, "primary", 400),
      $group-label-column-name-text:contrast-color($custom-palette, "primary", 500),
      $group-label-icon: color($custom-palette, "secondary", 600),
      $group-label-text:contrast-color($custom-palette, "primary", 500),
      $group-count-background: color($custom-palette, "secondary", 600),
      $group-count-text-color: color($custom-palette, "primary", 400),
      $expand-icon-color: color($custom-palette, "secondary", 600),
      $expand-icon-hover-color: color($custom-palette, "secondary", 300),
      $cell-active-border-color: color($custom-palette, "secondary", 600)
    );
    
    $custom-chips-theme: chip-theme(
      $background: color($custom-palette, "primary", 300),
      $text-color:contrast-color($custom-palette, "primary", 500),
      $hover-text-color:contrast-color($custom-palette, "primary", 600)
    );
    scss

    Definición de esquemas personalizados

    Puede ir aún más lejos y crear una estructura flexible que tenga todas las ventajas de un esquema. El esquema es la receta de un tema. Amplíe uno de los dos esquemas predefinidos que se proporcionan para cada componente. En nuestro caso, usaríamos light-grid.

    $custom-grid-schema: extend(
      $light-grid,
      (
        group-row-background: (color:('secondary', 100)),
        group-row-selected-background: (color:('primary', 400)),
        group-label-column-name-text: (color:('primary', 600)),
        group-label-icon: (color:('primary', 600)),
        group-label-text: (color:('secondary', 700)),
        group-count-background: (color:('primary', 600)),
        group-count-text-color: (color:('secondary', 400)),
        expand-icon-color: (color:('primary', 600)),
        expand-icon-hover-color: (color:('primary', 400))
      )
    );
    scss

    Para que se aplique el esquema personalizado, se debe extender (light o dark) globals. En realidad, todo el proceso consiste en proporcionar un componente con un esquema personalizado y agregarlo al tema de componente respectivo posteriormente.

    $my-custom-schema: extend(
      $light-material-schema, 
      ( 
        grid: $custom-grid-schema
      )
    );
    
    $custom-theme: grid-theme(
      $palette: $custom-palette,
      $schema: $my-custom-schema
    );
    scss

    Aplicar el tema personalizado

    La forma más sencilla de aplicar su tema es con una declaración @include ​ ​sass en el archivo de estilos global:

    @include css-vars($custom-theme);
    @include css-vars($custom-chips-theme);
    scss

    Tema de componente con alcance

    Para que el tema personalizado afecte solo a un componente específico, puede mover todos los estilos que acaba de definir desde el archivo de estilos globales al archivo de estilo del componente personalizado (incluida la importación del archivo index).

    De esta manera, debido a Angular ViewEncapsulation, los estilos solo se aplicarán al componente personalizado.

    Si el componente está usando un Emulated ViewEncapsulation, es necesario penetrar en este uso::ng-deep de encapsulación para estilizar los componentes que están dentro de la cuadrícula.

    En nuestro ejemplo, necesitamos usar::ng-deep para nuestro tema de fichas:

    @include css-vars($custom-theme);
    
    :host {
      ::ng-deep {
        @include chip($custom-chips-theme);
      }
    }
    scss

    Manifestación

    EXAMPLE

    La muestra no se verá afectada por el tema global seleccionado en Change Theme.

    Limitaciones conocidas

    Limitación Descripción
    La cantidad máxima de columnas agrupadas es 10. Si se agrupan más de 10 columnas, se genera un error.

    Referencias de API

    Recursos adicionales

    Nuestra comunidad es activa y siempre da la bienvenida a nuevas ideas.