Carga de red jerárquica bajo demanda

    La Ignite UI for Blazor IgbHierarchicalGrid permite una representación rápida al solicitar la cantidad mínima de datos que se recuperarán del servidor para que el usuario pueda ver el resultado en 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 Cargar a pedido, se puede configurar fácilmente para que funcione 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.

    Ejemplo de carga a pedido de cuadrícula jerárquica Blazor

    EXAMPLE
    MODULES
    DATA
    RAZOR
    JS
    CSS

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

    Proveedor de servicios remotos

    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:

    function getData(dataState) {
        return fetch(buildUrl(dataState))
            .then((result) => result.json());
    }
    razor

    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) {
        let qS = "";
        if (dataState) {
            if (dataState.rootLevel) {
                qS += `${dataState.key}`;
            } else {
                qS += `${dataState.parentKey}/${dataState.parentID}/${dataState.key}`;
            }
        }
        return `${DATA_URL}${qS}`;
    }
    razor

    Resultado

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

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

    Configuración de cuadrícula jerárquica

    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:

    <IgbHierarchicalGrid Id="hGrid" PrimaryKey="customerId" Height="600px">
        <IgbColumn Field="customerId" Hidden="true"></IgbColumn>
        <IgbColumn Field="companyName" Header="Company Name"></IgbColumn>
        <IgbColumn Field="contactName" Header="Contact Name"></IgbColumn>
        <IgbColumn Field="contactTitle" Header="Contact Title"></IgbColumn>
        <IgbColumn Field="address.country" Header="Country"></IgbColumn>
        <IgbColumn Field="address.phone" Header="Phone"></IgbColumn>
        <IgbRowIsland ChildDataKey="Orders" PrimaryKey="orderId">
            <IgbColumn Field="orderId" Hidden="true"></IgbColumn>
            <IgbColumn Field="shipAddress.country" Header="Ship Country"></IgbColumn>
            <IgbColumn Field="shipAddress.city" Header="Ship City"></IgbColumn>
            <IgbColumn Field="shipAddress.street" Header="Ship Address"></IgbColumn>
            <IgbColumn Field="orderDate" Header="Order Date" DataType="GridColumnDataType.Date"></IgbColumn>
            <IgbRowIsland ChildDataKey="Details" PrimaryKey="productId">
                <IgbColumn Field="productId" Hidden="true"></IgbColumn>
                <IgbColumn Field="quantity" Header="Quantity"></IgbColumn>
                <IgbColumn Field="unitPrice" Header="Unit Price"></IgbColumn>
                <IgbColumn Field="discount" Header="Discount"></IgbColumn>
            </IgbRowIsland>
        </IgbRowIsland>
    </IgbHierarchicalGrid>
    razor

    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 IgbHierarchicalGrid para ella y necesitamos obtener la referencia de la cuadrícula recién creada para establecer sus datos. Es por eso que cada IgbRowIsland 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 OnGridCreated.

    Dado que el GridCreated proporciona el evento parentID propiedad, una referencia a la isla fila como owner y el nuevo niño grid propiedad, se pasará como primer argumento. Solo nos falta información sobre el archivo primaryKey, pero podemos determinarlo fácilmente basándonos en la isla de fila ChildDataKey.

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

    <IgbHierarchicalGrid Id="hGrid" PrimaryKey="customerId" Height="600px">
        <IgbColumn Field="customerId" Hidden="true"></IgbColumn>
        <IgbColumn Field="companyName" Header="Company Name"></IgbColumn>
        <IgbColumn Field="contactName" Header="Contact Name"></IgbColumn>
        <IgbColumn Field="contactTitle" Header="Contact Title"></IgbColumn>
        <IgbColumn Field="address.country" Header="Country"></IgbColumn>
        <IgbColumn Field="address.phone" Header="Phone"></IgbColumn>
        <IgbRowIsland ChildDataKey="Orders" PrimaryKey="orderId" GridCreatedScript="OnGridCreated">
            <IgbColumn Field="orderId" Hidden="true"></IgbColumn>
            <IgbColumn Field="shipAddress.country" Header="Ship Country"></IgbColumn>
            <IgbColumn Field="shipAddress.city" Header="Ship City"></IgbColumn>
            <IgbColumn Field="shipAddress.street" Header="Ship Address"></IgbColumn>
            <IgbColumn Field="orderDate" Header="Order Date" DataType="GridColumnDataType.Date"></IgbColumn>
            <IgbRowIsland ChildDataKey="Details" PrimaryKey="productId" GridCreatedScript="OnGridCreated">
                <IgbColumn Field="productId" Hidden="true"></IgbColumn>
                <IgbColumn Field="quantity" Header="Quantity"></IgbColumn>
                <IgbColumn Field="unitPrice" Header="Unit Price"></IgbColumn>
                <IgbColumn Field="discount" Header="Discount"></IgbColumn>
            </IgbRowIsland>
        </IgbRowIsland>
    </IgbHierarchicalGrid>
    razor

    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. Para asegurarnos de que nuestra cuadrícula se renderiza antes de solicitar sus datos al servicio y asignarlos, usaremos el Rendered evento. 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:

    igRegisterScript("OnGridRendered", () => {
        const grid = document.getElementById("hGrid");
    
        getData({ parentID: null, rootLevel: true, key: "Customers" }).then(
            (data) => {
                grid.data = data;
                grid.markForCheck();
            });
    }, false)
    razor

    A continuación, solo necesitamos crear nuestro OnGridCreated 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:

    igRegisterScript("OnGridCreated", (args) => {
        const context = args.detail;
        const _parentKey = context.owner.childDataKey === "Orders" ? "Customers" : "Orders";
        const dataState = {
            key: context.owner.childDataKey,
            parentID: context.parentID,
            parentKey: _parentKey,
            rootLevel: false,
        };
    
        getData(dataState).then((data) => {
            context.grid.data = data;
            context.grid.markForCheck();
        });
    }, false)
    razor

    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 IgbHierarchicalGrid 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 IgbHierarchicalGrid 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í:

    igRegisterScript("OnGridRendered", () => {
        const grid = document.getElementById("hGrid");
    
        grid.isLoading = true;
    
        getData({ parentID: null, rootLevel: true, key: "Customers" }).then(
            (data) => {
                grid.isLoading = false;
                grid.data = data;
                grid.markForCheck();
            });
    }, false)
    
    igRegisterScript("OnGridCreated", (args) => {
        const context = args.detail;
        const _parentKey = context.owner.childDataKey === "Orders" ? "Customers" : "Orders";
        const dataState = {
            key: context.owner.childDataKey,
            parentID: context.parentID,
            parentKey: _parentKey,
            rootLevel: false,
        };
    
        context.grid.isLoading = true;
    
        getData(dataState).then((data) => {
            context.grid.isLoading = false;
            context.grid.data = data;
            context.grid.markForCheck();
        });
    }, false)
    razor

    Referencias de API

    Recursos adicionales

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