Ir para o conteúdo
Dominando a filtragem avançada em interfaces de grade Angular com Ignite UI

Dominando a filtragem avançada em interfaces de grade Angular com Ignite UI

Você sabe como habilitar a filtragem no estilo do Excel, operandos de filtragem personalizados, estratégias de filtragem personalizadas, filtragem avançada, filtragem programática ou filtragem remota? Este artigo mostrará como, incluindo snippets de código, exemplos e casos de uso.

9min de leitura

A filtragem é um recurso central de qualquer grade de dados, desempenhando um papel crítico em ajudar os usuários a encontrar e trabalhar com dados relevantes de forma rápida e eficiente. À medida que os conjuntos de dados crescem em tamanho e complexidade, os usuários precisam de mais do que apenas simples pesquisas de texto. É aqui que Ignite UI for Angular e o componente Grid entram em ação. Ele fornece uma API de filtragem robusta que oferece suporte a tudo, desde operações básicas até lógica avançada e personalizável, lidando com vários cenários de filtragem (como filtragem avançada, filtragem programática e outros) com facilidade.

Aqui está o que este post abordará para ajudá-lo a entender como tudo funciona e explorar as principais técnicas avançadas de filtragem para interfaces Grid complexas:

  • Filtragem no estilo do Excel
  • Operandos de filtragem personalizados
  • Estratégias de filtragem personalizadas
  • Filtragem avançada
  • Filtragem programática
  • Filtragem remota

Trabalhando com filtragem no estilo do Excel

A filtragem no estilo do Excel introduz paradigmas de interface do usuário familiares para Angular aplicativos, permitindo que os usuários apliquem filtros rápidos baseados em colunas com facilidade.

Quais são alguns dos casos de uso mais comuns?

  • Filtragem rápida em uma única coluna.
  • Várias condições de filtro por coluna.
  • Interface do usuário clara para usuários não técnicos.

Esse modo de filtragem é simples de implementar e é útil em aplicativos que exigem interfaces de filtragem simples, mas interativas.

Como habilitar a filtragem no estilo Excel?

Set [allowFiltering] to true and [filterMode] to 'excelStyleFilter': 
<igx-grid [data]="data" 
          [allowFiltering]="true" 
          [filterMode]="'excelStyleFilter'"> 
  <igx-column field="id" header="ID"></igx-column> 
  <!-- Additional columns --> 
</igx-grid>

Operandos de filtragem personalizados

Filtragem avançada

Os operandos internos, como Contains ou Equals, abrangem cenários comuns, mas quando seu aplicativo requer lógica específica do domínio, os operandos personalizados fornecem a flexibilidade para estender a estrutura de filtragem.

Quais são alguns dos casos de uso mais comuns?

  • Aplique regras de filtragem específicas do domínio.
  • Implemente uma lógica de correspondência flexível.
  • Suporta formatos de dados estruturados ou não padronizados.

Exemplo: Operando de correspondência de regex 

Esse operando de filtragem personalizado permite que os usuários apliquem expressões regulares para filtragem. Por exemplo, o regex ^\s*\S+\s+\S+\s+\S+\s+\S+\s*$ filtra nomes de produtos que contêm exatamente quatro palavras.

export class ExtendedStringFilteringOperand extends IgxStringFilteringOperand { 
  constructor() { 
    super(); 
    this.operations = [ 
      ...this.operations, // Keep default string operations 
      { 
        name: 'Regex Match', 
        iconName: 'search', 
        isUnary: false, 
        logic: (target: string, searchVal: string) => { 
          try { 
            const regex = new RegExp(searchVal); 
            return regex.test(target); 
          } catch (e) { 
            console.error('Invalid regex pattern:', e); 
            return false; 
          } 
        } 
      } 
    ]; 
  } 
}

Uso no Ignite UI for Angular Grid

public extendedStringFilteringOperand = ExtendedStringFilteringOperand.instance(); 
<igx-column field="productName" 
            header="Product Name" 
            dataType="string" 
            [filters]="extendedStringFilteringOperand"> 
</igx-column>

Estratégias úteis de filtragem personalizada para experimentar

Ignite UI Angular e filtragem avançada

A filtragem básica funciona bem para cenários simples. No entanto, quando seu aplicativo precisa limpar a entrada, dar suporte à lógica difusa ou aplicar regras diferentes por coluna, uma estratégia de filtragem personalizada oferece a flexibilidade necessária.

Com uma estratégia em vigor, você controla exatamente como a grade avalia cada valor em relação às condições do filtro.

Quais são alguns dos casos de uso mais comuns?

  • A entrada ou os dados devem ser transformados primeiro, como remover acentos, extrair números ou simplificar o texto.
  • A correspondência envolve tokens, frases parciais ou lógica difusa que vão além de simples operandos.
  • Colunas diferentes exigem comportamentos de filtragem exclusivos com base no tipo de dados ou na lógica de negócios.

Exemplo: Estratégia de correspondência de iniciais 

Essa estratégia filtra os dados transformando cada valor em suas iniciais (por exemplo, "John Doe" → "jd") e comparando-os com a condição de filtro.

export class InitialsFilteringStrategy extends FilteringStrategy { 
  public override filter(data: [], expressionsTree: IFilteringExpressionsTree): any[] { 
    const result: any[] = []; 
    if (!expressionsTree || !expressionsTree.filteringOperands || 
        expressionsTree.filteringOperands.length === 0 || !data.length) { 
      return data; 
    } 
    data.forEach((rec: any) => { 
      if (this.matchRecord(rec, expressionsTree)) { 
        result.push(rec); 
      } 
    }); 
    return result; 
  } 
  public override findMatchByExpression(rec: any, expr: IFilteringExpression, isDate?: boolean, isTime?: boolean, grid?: GridType): boolean { 
    const initials = this.getFieldValue(rec, expr.fieldName, isDate, isTime, grid) 
          .split(/\s+/) 
          .map(word => word[0]?.toLowerCase()) 
          .join(''); 
    return expr.condition?.logic?.(initials, expr.searchVal, expr.ignoreCase) ?? false; 
  } 
}

Nota: Para criar uma estratégia de filtragem personalizada, você pode implementar a interface IFilteringStrategy ou estender a classe base FilteringStrategy fornecida pela biblioteca.

Filtragem avançada

Para necessidades complexas de exploração de dados, o IgxGrid oferece uma interface de usuário de filtragem avançada. Esse recurso permite que os usuários criem consultas de várias condições em várias colunas usando uma interface de diálogo que dá suporte a expressões lógicas aninhadas (AND, OR).

Quais são alguns dos casos de uso mais comuns?  

  • Aplique condições de filtragem em várias colunas para isolar conjuntos de dados precisos.
  • Ideal para aplicativos em que usuários não técnicos precisam construir consultas complexas sem código.
  • Lide com cenários avançados que exigem lógica AND / OR aninhada para definir relações entre filtros.
  • Suporta perfeitamente strings, números, datas e tipos personalizados, tornando-o adequado para diversos conjuntos de dados.
  • Perfeito para interfaces de usuário com muitos dados, onde a filtragem profunda e interfaces amigáveis são essenciais.

Esse recurso oferece suporte a caixas de diálogo de filtragem internas e externas e se integra perfeitamente às APIs de grade, tornando-o ideal para aplicativos de Angular avançados em que a filtragem não é apenas uma preocupação da interface do usuário, mas uma parte essencial da estratégia de acesso a dados

Como ativar a filtragem avançada?

Há duas opções para começar a usar a Filtragem Avançada.

Opção 1: Filtragem Avançada Interna 

Habilite a filtragem avançada diretamente na grade:

<igx-grid [data]="data" [allowAdvancedFiltering]="true"> 
  <igx-column field="id" header="ID"></igx-column> 
  <!-- Other columns --> 
</igx-grid>

Isso adiciona uma opção "Filtragem avançada" ao menu da interface do usuário da grade.

Opção 2: caixa de diálogo de filtragem avançada externa 

Você também pode controlar a caixa de diálogo externamente usando o componente igx-advanced-filtering-dialog:

<igx-advanced-filtering-dialog [grid]="grid1"></igx-advanced-filtering-dialog> 
<igx-grid #grid1 [data]="data"> 
  <igx-column field="id" header="ID"></igx-column> 
  <!-- Other columns --> 
</igx-grid>

Essa configuração oferece mais controle sobre quando e como a caixa de diálogo é exibida.

Criando programaticamente expressões de filtragem avançada

Em muitos aplicativos, a filtragem nem sempre é disparada pela entrada direta do usuário. Talvez seja necessário aplicar filtros dinamicamente com base em exibições salvas, funções de usuário, lógica de negócios ou entradas externas.

O IgxGrid oferece suporte a isso com uma API flexível que permite criar e aplicar regras de filtragem programaticamente.

Core Concepts 

  • FilteringExpression: Representa uma única condição (por exemplo, status = 'Active')
  • FilteringExpressionsTree: agrupa expressões usando operadores lógicos (AND, OR) para formar consultas complexas

Exemplo: Construindo uma árvore de filtro 

public applyFiltering(department: string): void { 
  const today = new Date(); 
  const threeYearsAgo = new Date(today.getFullYear() - 3, today.getMonth(), today.getDate()); 
  const departmentAvgSalary = this.calculateAverageSalaryPerDepartment(department); 
  // Department filter: Department === specified value 
  const deptExpr: IFilteringExpression = { 
    fieldName: 'Department', 
    searchVal: department, 
    condition: IgxStringFilteringOperand.instance().condition('equals'), 
  }; 
  // Tenure filter: HireDate before 3 years ago 
  const tenureExpr: IFilteringExpression = { 
    fieldName: 'HireDate', 
    searchVal: threeYearsAgo, 
    condition: IgxDateFilteringOperand.instance().condition('before'), 
  }; 
  // Salary filter: GrossSalary within ±5% of department average 
  const salaryMinExpr: IFilteringExpression = { 
    fieldName: 'GrossSalary', 
    searchVal: departmentAvgSalary * 0.95, 
    condition: IgxNumberFilteringOperand.instance().condition('greaterThanOrEqualTo'), 
  }; 
  const salaryMaxExpr: IFilteringExpression = { 
    fieldName: 'GrossSalary', 
    searchVal: departmentAvgSalary * 1.05, 
    condition: IgxNumberFilteringOperand.instance().condition('lessThanOrEqualTo'), 
  }; 
  // Combine salary range conditions with OR 
  const salaryExprTree = new FilteringExpressionsTree(FilteringLogic.Or); 
  salaryExprTree.filteringOperands.push(salaryMinExpr, salaryMaxExpr); 
  // Build main AND tree with all filters 
  const mainExprTree = new FilteringExpressionsTree(FilteringLogic.And); 
  mainExprTree.filteringOperands.push(deptExpr, tenureExpr, salaryExprTree); 
  // Apply filters to the grid 
  this.treeGrid.advancedFilteringExpressionsTree = mainExprTree; 
}

Este exemplo demonstra como criar filtros programaticamente para mostrar os funcionários do departamento de 'Tecnologia', contratados há pelo menos 3 anos, cujos salários brutos estão dentro de ±5% da média do departamento.

Quais são alguns dos benefícios?

  • Controle total sobre o comportamento de filtragem.
  • Integre-se facilmente com as configurações do usuário ou filtros salvos.
  • Compatível com a interface do usuário de filtragem avançada (os filtros aplicados programaticamente podem ser editados por meio da interface do usuário).

Essa abordagem é ideal quando os filtros devem ser aplicados automaticamente com base no contexto, ou mostrando dados específicos do departamento para determinados usuários, ou pré-filtrando com base em uma seleção de painel.

Filtragem remota

Ao trabalhar com grandes conjuntos de dados, a filtragem do lado do cliente pode não ser eficiente ou escalável. Nesses casos, o IgxGrid oferece suporte à filtragem remota, em que as expressões de filtro são construídas no cliente e enviadas ao servidor para processamento.

Essa abordagem é ideal para grades virtualizadas, APIs paginadas ou cenários em que os sistemas de back-end executam o trabalho pesado.

Quais são alguns dos casos de uso mais comuns?

  • Grades virtualizadas com paginação do lado do servidor.
  • Painéis que exigem a consulta de grandes conjuntos de dados.
  • Garantir que os filtros sejam aplicados no lado do servidor para segurança ou privacidade de dados.

Como funciona

  1. Os usuários interagem com a interface de filtragem do IgxGrid.
  1. A grade cria um FilteringExpressionsTree representando filtros ativos.
  1. Você serializa essa árvore de filtro e a inclui nas solicitações de API.
  1. Seu servidor processa os filtros e retorna dados correspondentes.

Exemplo: Gerar consulta de filtro para sua API 

private buildFilterQuery(): string { 
  const expressionsTree = this.grid.filteringExpressionsTree; 
  if (!expressionsTree || expressionsTree.filteringOperands.length === 0) { 
    return ''; 
  } 
  const filterParts: string[] = []; 
  expressionsTree.filteringOperands.forEach((expr: IFilteringExpression) => { 
    const field = expr.fieldName; 
    const condition = expr.condition.name; 
    const value = encodeURIComponent(expr.searchVal); 
    filterParts.push(`${field} ${condition} ${value}`); 
  }); 
  return filterParts.join(' or '); 
} 
private buildDataUrl(): string { 
  const filterQuery = this.buildFilterQuery(); 
  const baseUrl = 'https://myapi.example.com/employees'; 
  return filterQuery ? `${baseUrl}?$filter=${filterQuery}` : baseUrl; 
}

Uso

const apiUrl = this.buildDataUrl(); 
this.http.get(apiUrl).subscribe((data) => { 
  this.grid.data = data; 
}); 
//Generated URL example 
https://services.odata.org/V4/Northwind/Northwind.svc/Products?$filter=UnitPrice gt 50 and UnitsInStock gt 10

Dica útil de integração de back-end

Verifique se o servidor pode interpretar e aplicar a lógica de filtro. Dependendo da sua tecnologia de back-end, você pode:

  • Mapeie operadores (por exemplo, contém, é igual) para equivalentes SQL ou NoSQL.
  • Analise grupos AND/OR aninhados da FilteringExpressionsTree.
  • Aplique filtragem sensível ao tipo (por exemplo, cadeias de caracteres, números, datas).

Embrulhar

Para aproveitar ao máximo os recursos de filtragem do IgxGrid, explore a documentação Ignite UI for Angular, confira nossos Exemplos de grade para ver os recursos de filtragem em ação e sinta-se à vontade para experimentar a combinação de filtragem formatada e operandos personalizados para uma experiência de usuário altamente personalizada.

Com essas ferramentas, você pode criar experiências de dados de nível empresarial que capacitam os usuários a explorar, analisar e agir com base em seus dados com mais eficiência e com mais insights.

Solicite uma demonstração