Carga de grade hierárquica sob demanda
O Ignite UI for Blazor IgbHierarchicalGrid
permite uma renderização rápida, solicitando a quantidade mínima de dados a serem recuperados do servidor para que o usuário possa ver o resultado em exibição e interagir com os dados visíveis o mais rápido possível. Inicialmente, apenas os dados da grade raiz são recuperados e renderizados, somente depois que o usuário expandir uma linha contendo uma grade filho, ele receberá os dados dessa grade filho específica. Esse mecanismo, também conhecido como Load on Demand, pode ser facilmente configurado para funcionar com qualquer dado remoto.
Este tópico demonstra como configurar a Carga sob Demanda criando um Provedor de Serviços Remotos que se comunica com um serviço remoto já disponível. Aqui está a demonstração de trabalho e, mais tarde, vamos analisá-la passo a passo e descrever o processo de criação.
Blazor Hierarchical Grid Load On Demand Example
Remote Service Provider
Primeiro, prepararemos nosso provedor de serviços para que estejamos prontos para obter os dados necessários para a grade hierárquica.
Obtendo dados básicos
Estaremos nos comunicando com nosso serviço de back-end pelo protocolo HTTP usando a fetch()
função global que os navegadores fornecem. Dessa forma, para obter nossos dados, precisaremos deste método simples em nosso serviço:
function getData(dataState) {
return fetch(buildUrl(dataState))
.then((result) => result.json());
}
Como você pode ver buildUrl()
, será o método que gerará nossa url com base nos dados que recebemos. Retornamos uma promessa, pois ela é executada de forma assíncrona. Dessa forma, podemos subscrevê-lo posteriormente, processá-lo ainda mais em nosso aplicativo e passá-lo para nossa grade.
Construindo nossa URL de solicitação
Em seguida, definiremos como devemos construir nossa URL para a solicitação GET. É aqui que poderemos obter os dados para nossa grade principal, mas também para qualquer grade secundária dentro dela. Usaremos os Customers
dados daqui para nosso nível raiz e uso Orders
e Details
para os níveis inferiores. O modelo será diferente por aplicativo, mas usaremos o seguinte:

O que precisamos primeiro é da key
nossa tabela para determinar de onde obter os dados para a grade desejada, a chave primária da linha pai e seu ID exclusivo.
Vamos definir tudo isso no dataState
objeto. Um exemplo:
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}`;
}
Resultado
Finalmente, é assim que nosso serviço remoto seria:
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}`;
}
Hierarchical Grid Setup
Em seguida, configuraremos nossa grade hierárquica e a conectaremos ao nosso provedor de serviços remotos.
Definição de modelo
Primeiro, definiremos nosso modelo de grade hierárquica com os níveis de hierarquia que esperamos ter. Sabemos que nossa grade PrimaryKey
raiz para os clientes é deles customerId
, para seus pedidos no primeiro nível -orderId
e respectivamente para detalhes do pedido -productId
. Conhecer cada tabela de banco de dados e suas chaves nos permite definir nosso modelo 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>
No entanto, há uma coisa faltando em nosso modelo, que são os dados para nossa grade hierárquica de nível raiz e, eventualmente, seus filhos.
Definiremos facilmente os dados da grade raiz depois de obter seus dados do serviço em nosso código posteriormente, pois podemos usar a Id="hGrid"
referência.
Definir os dados para qualquer filho que foi expandido é um pouco diferente. Quando uma linha é expandida pela primeira vez, um novo filho IgbHierarchicalGrid
é renderizado para ela e precisamos obter a referência da grade recém-criada para definir seus dados. É por isso que cada IgbRowIsland
componente fornece o GridCreated
evento que é acionado quando uma nova grade filho é criada para essa ilha de linha específica. Podemos usar isso para obter a referência necessária para a nova grade, solicitar seus dados do serviço e aplicá-los.
Podemos usar um método para todas as ilhas de linha, já que construímos nosso serviço de modo que ele precise apenas de informações se for o nível raiz, a chave da ilha de linha, a chave primária da linha pai e seu identificador exclusivo. Todas essas informações podem ser acessadas diretamente dos argumentos do evento ou da ilha de linha responsável por disparar o evento.
Vamos nomear o método que usaremos OnGridCreated
.
Como o GridCreated
evento fornece a parentID
propriedade, uma referência à ilha de linha como owner
e à nova propriedade filho grid
, ela será passada como o primeiro argumento. Faltam apenas informações sobre a linha primaryKey
pai, mas podemos determinar isso facilmente com base na ilha ChildDataKey
da linha.
O arquivo de modelo, com essas alterações adicionadas, ficaria assim:
<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>
Conectando nosso serviço
Uma de nossas etapas finais agora será conectar nosso serviço criado anteriormente à nossa grade hierárquica.
Obteremos uma referência à nossa grade raiz para definir seus dados. Para garantir que nossa grade seja renderizada antes de solicitarmos seus dados do serviço e atribuí-los, usaremos o Rendered
evento. Como não tem pais, só podemos passar o que rootLevel
é verdade, e a chave para isso, para o getData
nosso serviço. Como ele retorna uma promessa, precisaremos assiná-la:
igRegisterScript("OnGridRendered", () => {
const grid = document.getElementById("hGrid");
getData({ parentID: null, rootLevel: true, key: "Customers" }).then(
(data) => {
grid.data = data;
grid.markForCheck();
});
}, false)
Em seguida, precisamos apenas criar nosso OnGridCreated
método que solicitará dados para qualquer nova grade filha criada.
Será semelhante a obter os dados da grade de nível raiz, só que desta vez precisaremos passar mais informações, como parentID
e parentKey
. rootLevel
será falso para qualquer criança:
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)
Com isso, a configuração do nosso aplicativo está quase pronta. Esta última etapa visa melhorar a experiência do usuário, informando ao usuário que os dados ainda estão sendo carregados para que ele não precise olhar para uma grade vazia enquanto isso. É por isso que o suporta IgbHierarchicalGrid
um indicador de carga que pode ser exibido enquanto a grade está vazia. Se novos dados forem recebidos, o indicador de carregamento será ocultado e os dados serão renderizados.
Configuração da indicação de carga
O IgbHierarchicalGrid
pode exibir um indicador de carregamento definindo a IsLoading
propriedade como true enquanto não houver dados. Precisamos configurá-lo inicialmente para a grade raiz e também ao criar novas grades filhas, até que seus dados sejam carregados. Sempre podemos defini-lo como true em nosso modelo, mas queremos ocultá-lo e exibir que a grade não tem dados se o serviço retornar uma matriz vazia definindo-a como false.
Nesse caso, a versão final de nossa configuração ficaria assim:
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)
API References
Additional Resources
Nossa comunidade é ativa e sempre acolhedora para novas ideias.