Carga de red jerárquica bajo demanda

    El Ignite UI for Web Components IgcHierarchicalGridComponent permite una representación rápida al solicitar que se recupere la cantidad mínima de datos del servidor para que el usuario pueda ver el resultado a la vista e interactuar con los datos visibles lo más rápido posible. Inicialmente, solo se recuperan y representan los datos de la cuadrícula raíz, solo después de que el usuario expanda una fila que contenga una cuadrícula secundaria, recibirá los datos de esa cuadrícula secundaria en particular. Este mecanismo, también conocido como Load on Demand, se puede configurar fácilmente para trabajar con cualquier dato remoto.

    En este tema se muestra cómo configurar la carga a petición mediante la creación de un proveedor de servicios remotos que se comunica con un servicio remoto ya disponible. Aquí está la demostración de trabajo y luego la revisaremos paso a paso y describiremos el proceso de creación.

    Web Components Hierarchical Grid Load On Demand Example

    EXAMPLE
    DATA
    TS
    HTML
    CSS

    Like this sample? Get access to our complete Ignite UI for Web Components toolkit and start building your own apps in minutes. Download it for free.

    Remote Service Provider

    Primero, prepararemos a nuestro proveedor de servicios para que estemos listos para obtener los datos que necesitaríamos para la cuadrícula jerárquica.

    Obteniendo datos básicos

    Nos comunicaremos con nuestro servicio de backend a través del protocolo HTTP utilizando la fetch() función global que proporcionan los navegadores. De esta manera, para obtener nuestros datos, necesitaremos este sencillo método en nuestro servicio:

    export function getData(dataState: any): any {
        return fetch(buildUrl(dataState))
            .then((result) => result.json());
    }
    ts

    Como veis buildUrl() será el método que generará nuestra url en base a los datos que hayamos recibido. Devolvemos una promesa, ya que esta se ejecuta de forma asíncrona. De esa manera podemos suscribirnos más tarde a ella, procesarla más adelante en nuestra aplicación y pasarla a nuestra red.

    Construyendo nuestra URL de solicitud

    A continuación, definiremos cómo debemos construir nuestra URL para la solicitud GET. Aquí es donde podremos obtener los datos de nuestra cuadrícula principal, pero también de cualquier cuadrícula secundaria dentro de ella. Usaremos los Customers datos de aquí para nuestro nivel raíz y uso Orders y Details para los niveles inferiores. El modelo será diferente según la aplicación, pero utilizaremos el siguiente:

    Lo primero que necesitamos es el key de nuestra tabla para determinar de dónde obtener los datos para la cuadrícula deseada, la clave principal de la fila principal y su ID único.

    Todo esto lo definiremos en el dataState objeto. Un ejemplo:

    const dataState: {
        key: string;
        parentID: any;
        parentKey: string;
        rootLevel: boolean;
    } = {
        //...
    };
    
    function buildUrl(dataState: any) {
        let qS = "";
        if (dataState) {
            if (dataState.rootLevel) {
                qS += `${dataState.key}`;
            } else {
                qS += `${dataState.parentKey}/${dataState.parentID}/${dataState.key}`;
            }
        }
        return `${URL}${qS}`;
    }
    ts

    Resultado

    Finalmente, así es como se vería nuestro servicio remoto:

    const URL = `https://data-northwind.indigo.design/`;
    
    export function getData(dataState: any): any {
        return fetch(buildUrl(dataState))
            .then((result) => result.json());
    }
    
    function buildUrl(dataState: any) {
        let qS = "";
        if (dataState) {
            if (dataState.rootLevel) {
                qS += `${dataState.key}`;
            } else {
                qS += `${dataState.parentKey}/${dataState.parentID}/${dataState.key}`;
            }
        }
        return `${URL}${qS}`;
    }
    ts

    Hierarchical Grid Setup

    A continuación configuraremos nuestra red jerárquica y la conectaremos a nuestro proveedor de servicios remoto.

    Definición de plantilla

    Primero definiremos nuestra plantilla de cuadrícula jerárquica con los niveles de jerarquía que esperamos tener. Sabemos que nuestra red PrimaryKey raíz para los clientes es la suya customerId, para sus pedidos en el primer nivel -orderId y respectivamente para los detalles de los pedidos-productId. Conocer cada tabla de la base de datos y sus claves nos permite definir nuestra plantilla inicial:

    <igc-hierarchical-grid id="hGrid" primary-key="customerId" height="600px">
        <igc-column field="customerId" hidden="true"></igc-column>
        <igc-column field="companyName" header="Company Name"></igc-column>
        <igc-column field="contactName" header="Contact Name"></igc-column>
        <igc-column field="contactTitle" header="Contact Title"></igc-column>
        <igc-column field="address.country" header="Country"></igc-column>
        <igc-column field="address.phone" header="Phone"></igc-column>
        <igc-row-island child-data-key="Orders" primary-key="orderId">
            <igc-column field="orderId" hidden="true"></igc-column>
            <igc-column field="shipAddress.country" header="Ship Country"></igc-column>
            <igc-column field="shipAddress.city" header="Ship City"></igc-column>
            <igc-column field="shipAddress.street" header="Ship Address"></igc-column>
            <igc-column field="orderDate" header="Order Date" data-type="date"></igc-column>
            <igc-row-island child-data-key="Details" primary-key="productId">
                <igc-column field="productId" hidden="true"></igc-column>
                <igc-column field="quantity" header="Quantity"></igc-column>
                <igc-column field="unitPrice" header="Unit Price"></igc-column>
                <igc-column field="discount" header="Discount"></igc-column>
            </igc-row-island>
        </igc-row-island>
    </igc-hierarchical-grid>
    html

    Sin embargo, hay una cosa que falta en nuestra plantilla, y son los datos de nuestra cuadrícula jerárquica de nivel raíz y, finalmente, sus hijos.

    Estableceremos fácilmente los datos de la cuadrícula raíz después de obtener sus datos del servicio en nuestro código más adelante, ya que podemos usar la id="hGrid" referencia.

    La configuración de los datos para cualquier elemento secundario que se haya expandido es un poco diferente. Cuando una fila se expande por primera vez, se representa un nuevo elemento secundario IgcHierarchicalGridComponent para ella y necesitamos obtener la referencia de la cuadrícula recién creada para establecer sus datos. Es por eso que cada IgcRowIsland componente proporciona el GridCreated evento que se desencadena cuando se crea una nueva cuadrícula secundaria para esa isla de filas específica. Podemos usar eso para obtener la referencia que necesitamos para la nueva cuadrícula, solicitar sus datos al servicio y aplicarlos.

    Podemos usar un método para todas las islas de filas, ya que creamos nuestro servicio de modo que solo necesite información si es el nivel raíz, la clave de la isla de filas, la clave principal de la fila principal y su identificador único. Se puede acceder a toda esta información directamente desde los argumentos del evento o desde la isla de fila responsable de desencadenar el evento.

    Vamos a nombrar el método que vamos a utilizar gridCreated.

    Dado que el GridCreated evento proporciona la parentID propiedad, una referencia a la isla de filas como owner y la nueva propiedad secundaria grid, se pasará como primer argumento. Solo nos falta información sobre la fila principal, pero podemos pasarla fácilmente como un segundo argumento, dependiendo de la isla de primaryKey filas que vinculemos.

    El archivo de plantilla, con estos cambios agregados, se vería así:

    <igc-hierarchical-grid id="hGrid" primary-key="customerId" height="600px">
        <igc-column field="customerId" hidden="true"></igc-column>
        <igc-column field="companyName" header="Company Name"></igc-column>
        <igc-column field="contactName" header="Contact Name"></igc-column>
        <igc-column field="contactTitle" header="Contact Title"></igc-column>
        <igc-column field="address.country" header="Country"></igc-column>
        <igc-column field="address.phone" header="Phone"></igc-column>
        <igc-row-island id="ordersRowIsland" child-data-key="Orders" primary-key="orderId">
            <igc-column field="orderId" hidden="true"></igc-column>
            <igc-column field="shipAddress.country" header="Ship Country"></igc-column>
            <igc-column field="shipAddress.city" header="Ship City"></igc-column>
            <igc-column field="shipAddress.street" header="Ship Address"></igc-column>
            <igc-column field="orderDate" header="Order Date" data-type="date"></igc-column>
            <igc-row-island id="orderDetailsRowIsland" child-data-key="Details" primary-key="productId">
                <igc-column field="productId" hidden="true"></igc-column>
                <igc-column field="quantity" header="Quantity"></igc-column>
                <igc-column field="unitPrice" header="Unit Price"></igc-column>
                <igc-column field="discount" header="Discount"></igc-column>
            </igc-row-island>
        </igc-row-island>
    </igc-hierarchical-grid>
    html
    constructor() {
        const ordersRowIsland = document.getElementById("ordersRowIsland");
        const orderDetailsRowIsland = document.getElementById("orderDetailsRowIsland");
    
        ordersRowIsland.addEventListener("gridCreated", (event: any) => {
            this.gridCreated(event, "Customers");
        });
    
        orderDetailsRowIsland.addEventListener("gridCreated", (event: any) => {
            this.gridCreated(event, "Orders");
        });
    }
    ts

    Conectando nuestro servicio

    Uno de nuestros últimos pasos ahora será conectar nuestro servicio creado previamente a nuestra cuadrícula jerárquica.

    Obtendremos una referencia a nuestra cuadrícula raíz para establecer sus datos. Como no tiene padres, solo podemos pasar que rootLevel es verdad, y la clave para ello, a la getData de nuestro servicio. Dado que devuelve una promesa, necesitaremos suscribirnos a ella:

    constructor() {
        const hierarchicalGrid = document.getElementById("hGrid") as IgcHierarchicalGridComponent;
    
        getData({ parentID: null, rootLevel: true, key: "Customers" }).then((data: any) => {
            hierarchicalGrid.data = data;
            hierarchicalGrid.markForCheck();
        });
    }
    ts

    A continuación, solo necesitamos crear nuestro gridCreated método que solicitará datos para cualquier nueva cuadrícula secundaria creada.

    Será similar a obtener los datos de la cuadrícula de nivel raíz, solo que esta vez necesitaremos pasar más información, como parentID y parentKey. rootLevel será falso para cualquier niño:

    public gridCreated(event: CustomEvent<IgcGridCreatedEventArgs>, _parentKey: string) {
        const context = event.detail;
        const dataState = {
            key: context.owner.childDataKey,
            parentID: context.parentID,
            parentKey: _parentKey,
            rootLevel: false
        };
    
        getData(dataState).then((data: any[]) => {
            context.grid.data = data;
            context.grid.markForCheck();
        });
    }
    ts

    Con esto, la configuración de nuestra aplicación está casi terminada. Este último paso tiene como objetivo mejorar la experiencia del usuario informando al usuario de que los datos aún se están cargando para que no tenga que mirar una cuadrícula vacía mientras tanto. Es por eso que IgcHierarchicalGridComponent admite un indicador de carga que se puede mostrar mientras la cuadrícula está vacía. Si se reciben nuevos datos, el indicador de carga se ocultará y los datos se renderizarán.

    Configuración de indicación de carga

    Puede IgcHierarchicalGridComponent mostrar un indicador de carga estableciendo la IsLoading propiedad en true mientras no hay datos. Necesitamos configurarlo inicialmente para la cuadrícula raíz y también al crear nuevas cuadrículas hijas, hasta que se carguen sus datos. Siempre podemos establecerlo en true en nuestra plantilla, pero queremos ocultarlo y mostrar que la cuadrícula no tiene datos si el servicio devuelve una matriz vacía configurándola en false.

    En este caso, la versión final de nuestra configuración se vería así:

    constructor() {
        const hierarchicalGrid = document.getElementById("hGrid") as IgcHierarchicalGridComponent;
        const ordersRowIsland = document.getElementById("ordersRowIsland");
        const orderDetailsRowIsland = document.getElementById("orderDetailsRowIsland");
    
        ordersRowIsland.addEventListener("gridCreated", (event: any) => {
            this.gridCreated(event, "Customers");
        });
    
        orderDetailsRowIsland.addEventListener("gridCreated", (event: any) => {
            this.gridCreated(event, "Orders");
        });
    
        hierarchicalGrid.isLoading = true;
    
        getData({ parentID: null, rootLevel: true, key: "Customers" }).then((data: any) => {
            hierarchicalGrid.isLoading = false;
            hierarchicalGrid.data = data;
            hierarchicalGrid.markForCheck();
        });
    }
    
    public gridCreated(event: CustomEvent<IgcGridCreatedEventArgs>, _parentKey: string) {
        const context = event.detail;
        const dataState = {
            key: context.owner.childDataKey,
            parentID: context.parentID,
            parentKey: _parentKey,
            rootLevel: false
        };
    
        context.grid.isLoading = true;
    
        getData(dataState).then((data: any[]) => {
            context.grid.isLoading = false;
            context.grid.data = data;
            context.grid.markForCheck();
        });
    }
    ts

    API References

    Additional Resources

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