Este guia técnico demonstra como configurar uma pesquisa assíncrona em uma estrutura de árvore utilizando jQuery zTree, com foco na localização de nós folha. A solução envolve integração entre front-end em JavaScript/JQuery e back-end em Java com Spring MVC.
Configuração do Front-end
O código HTML e JavaScript abaixo ilustra a inicialização da árvore com carregamneto assíncrono e a implementação da funcionalidade de pesquisa. Os parâmetros de busca são transmitidos ao servidor via requisições AJAX.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="resources/zTreeStyle/zTreeStyle.css" type="text/css">
<link rel="stylesheet" type="text/css" href="resources/bootstrap/bootstrap.min.css">
<title>Exemplo de Árvore Assíncrona</title>
</head>
<body>
<div class="container">
<h4>Demonstração de Carregamento Assíncrono com Ztree</h4>
<input type="text" id="campoBusca" /> <input type="button" id="btnBuscar" value="Pesquisar" onclick="executarPesquisa()"/>
<ul id="arvoreDados" class="ztree"></ul>
</div>
</body>
<script src="resources/js/jquery.min.js"></script>
<script type="text/javascript" src="resources/js/jquery.ztree.all.min.js"></script>
<script type="text/javascript" src="resources/js/jquery.ztree.exhide.min.js"></script>
<script type="text/javascript">
var configuracoes = {
assincrono: {
ativo: true,
url: "buscarNos",
autoParam: ["id", "idPai", "rotulo"],
filtro: tratarDados
},
dados: {
dadosSimples: {
ativo: true,
chaveId: 'id',
chavePai: 'idPai',
raizPai: 0
}
},
visual: {
exibirIcone: false
},
callback: {
aoNoCriado: callbackNoCriado
}
};
$(document).ready(function(){
inicializarArvore();
});
function executarPesquisa(){
var termo = $.trim($("#campoBusca").val());
var instanciaArvore = $.fn.zTree.getZTreeObj("arvoreDados");
if(termo !== ""){
termo = encodeURI(encodeURI(termo));
instanciaArvore.configuracoes.assincrono.outrosParametros=["param", termo];
} else {
instanciaArvore.configuracoes.assincrono.outrosParametros=[];
}
instanciaArvore.reAsyncChildNodes(null, "refresh");
}
function callbackNoCriado(evento, idArvore, no){
var termo = $.trim($("#campoBusca").val());
var instanciaArvore = $.fn.zTree.getZTreeObj(idArvore);
if(termo !== "" && no.ehPai){
instanciaArvore.reAsyncChildNodes(no, "refresh", false);
}
}
function tratarDados(idArvore, noPai, nosFilhos) {
return nosFilhos;
}
function inicializarArvore(){
$.ajax({
url: "buscarNos",
type: "post",
dataType: "json",
sucesso: function(dados){
var instanciaArvore = $.fn.zTree.init($("#arvoreDados"), configuracoes, dados);
var noRaiz = instanciaArvore.getNodeByParam('idPai',0,null);
instanciaArvore.expandNode(noRaiz, true, false, false, false);
},
erro: function(){
console.error("Falha ao carregar dados iniciais da árvore.");
}
});
}
</script>
</html>
Modelo de Dados no Back-end
A classe abaixo representa um nó da árvore, com propriedades para identificação, hierarquia e estado.
package com.exemplo.modelo;
public class NoArvore {
private String id;
private String idPai;
private String nome;
private String expandido;
private String possuiFilhos;
public NoArvore(String id, String idPai, String nome, String expandido, String possuiFilhos) {
this.id = id;
this.idPai = idPai;
this.nome = nome;
this.expandido = expandido;
this.possuiFilhos = possuiFilhos;
}
// Métodos getters e setters omitidos para brevidade
public String getId() { return id; }
public void setId(String id) { this.id = id; }
public String getIdPai() { return idPai; }
public void setIdPai(String idPai) { this.idPai = idPai; }
public String getNome() { return nome; }
public void setNome(String nome) { this.nome = nome; }
public String getExpandido() { return expandido; }
public void setExpandido(String expandido) { this.expandido = expandido; }
public String getPossuiFilhos() { return possuiFilhos; }
public void setPossuiFilhos(String possuiFilhos) { this.possuiFilhos = possuiFilhos; }
}
Controlador Spring MVC
O endpoint REST abaixo fornece os nós da árvore de forma assíncrona, simulando uma estrutura hierárquica para demonstração.
package com.exemplo.controlador;
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.exemplo.modelo.NoArvore;
@Controller
public class ControladorArvore {
@RequestMapping("/buscarNos")
@ResponseBody
public List<NoArvore> buscarNos(String id, String idPai, String nome) {
List<NoArvore> listaNos = new ArrayList<>();
if(id == null){
listaNos.add(new NoArvore("1","0","Hardware","false","true"));
listaNos.add(new NoArvore("2","0","Software","false","true"));
return listaNos;
}
switch(id) {
case "1":
listaNos.add(new NoArvore("10","1","Placa-mãe","false","true"));
listaNos.add(new NoArvore("11","1","Memória","false","true"));
listaNos.add(new NoArvore("12","1","Processador","false","true"));
break;
case "2":
listaNos.add(new NoArvore("20","2","Java","false","true"));
listaNos.add(new NoArvore("21","2","TypeScript","false","true"));
listaNos.add(new NoArvore("22","2","Python","false","true"));
break;
case "10":
listaNos.add(new NoArvore("100",id,"Modelo_A","false","true"));
listaNos.add(new NoArvore("101",id,"Modelo_B","false","false"));
break;
case "100":
listaNos.add(new NoArvore("1000",id,"Versão_1.0","false","false"));
break;
}
return listaNos;
}
}
Princípios de Funcionamento
- O parâmetro de pesquisa é transmitido ao servidor usando a propriedade
outrosParametrosdo zTree; quando vazio, o array deve ser reinicializado para evitar envio de dados anteriores. - No retorno de chamada
aoNoCriado, cada nó pai é carregado assincronamente ao ser criado, incorporando o termo de busca para filtragem no servidor. - A inicialização da árvore ocorre via carregamento manual do primeiro nível, seguido de expansão programática do nó raiz.
- A busca efetiva requer que o back-end implemente lógica de filtragem com base no parâmetro
param; o exemplo apresentado usa dados estáticos para ilustração.