[Resolvido - com varias soluções] JSF ajax aggregation - segurança no limite de requisições
10 respostas
gilbueno
Boa tarde, estou fazendo uma aplicação que possui um campo de busca de ruas
que conforme o usuario digita o nome da rua um componente select mostra as ruas
com o nome parecido
consegui fazer numa boa com f:ajax o problema é que preciso fazer agora
uma “aggregation”, ou seja, quero que não ocorra a busca a cada tecla que o
usuario digita para não sobrecarregar o servidor, quero apenas de 1 em 1 segundos
ou algo parecido.
consegui fazer, mas o componente não é renderizado na hora certa (o response do ajax
é executado antes do método terminar).
alguem tem alguma noção de como fazer esse aggregation?
O primefaces possui um elemento chamando <p:poll> e ele próprio faz as requisições ajax de acordo com o tempo estabelecido.
Eu sei que tem outro framework que tem um componente com o mesmo comportamento, mas não sei dizer qual;
Se tu não esta utilizando nenhum framework, voce tera que fazer isso na unha. Um meio de tu fazer isso seria através de js dar um setInterval() com alguma função que verifique de alguma maneira se o método já terminou, e apartir disso realizar a requisição ajax.
Se tu puder decorrer mais sobre o seu problema…
luiz.portnoy
Ygor:
O primefaces possui um elemento chamando <p:poll> e ele próprio faz as requisições ajax de acordo com o tempo estabelecido.
Eu sei que tem outro framework que tem um componente com o mesmo comportamento, mas não sei dizer qual;
Se tu não esta utilizando nenhum framework, voce tera que fazer isso na unha. Um meio de tu fazer isso seria através de js dar um setInterval() com alguma função que verifique de alguma maneira se o método já terminou, e apartir disso realizar a requisição ajax.
Se tu puder decorrer mais sobre o seu problema…
No próprio primefaces tem o AutoComplete que faz isso.
Espero ter ajudado
Ygor
É verdade!
Tinha me esquecido deste componente. Muito mais elegante do que ficar POGeando por ae hehehehe!
Olhando na documentação dele, ele possui os atributos ‘minQueryLength’ e ‘queryDelay’ que se encaixam perfeitamente neste problema.
Agora se nao poder utilizar o Prime, não consigo pensar em outra maneira se não em JavaScript
gilbueno
Obrigado por ambas as respostas,
antes de vocês responderem eu cogitei em fazer com algum framework
mas na empresa onde eu trabalho não é insentivado o uso de frameworks fora dos padrões,
eu uso apenas JSF 2 e JPA.
por isso optei por fazer em javascript, oque na minha opnião não é a melhor maneira.
estou tendo alguns problemas simples de javascript mas já consegui fazer oque eu precisava.
amanha vou postar o código aqui
muito obrigado
gilbueno
[size=18]JSF Aggregation sem o uso de componentes fora do padrão:[/size]
@ManagedBean@SessionScopedpublicclassSemCookiesBean{privateStringrua;privateList<Cep>ruas;privateStringruaBusca;privateStringultimaRuaBusca;//para o controle de requisições, não queremos a mesma busca várias vezesprivatelongtempoUltimaRuaBusca;//não queremos que o usuario faça mais do que 1 busca por segundo@EJBBancoDeDadosbd;publicvoidsetRuaBusca(StringruaBusca){this.ruaBusca=ruaBusca;popularApartirDeRuaBusca();}//é acessado apenas pelo setRuaBusca por não estarmos usando f:ajax e não temos a possibilidade de passar um listener// ao invéz de f:ajax utilizamos um script para criar um atraso para não haver sobrecargapublicvoidpopularApartirDeRuaBusca(){//popula a lista de ruas de acordo com o estado, cidade e ruaBuscaif(ultimaRuaBusca==null||!ultimaRuaBusca.equals(ruaBusca)){if(tempoUltimaRuaBusca==0||tempoUltimaRuaBusca+1000<=System.currentTimeMillis()){//apartir daqui é parte do meu sistema e irrelevalte à vocêsif(estado!=null&&!estado.isEmpty()&&cidade!=null&&!cidade.isEmpty()&&removerTipoDoLogradouro(ruaBusca)!=null&&!removerTipoDoLogradouro(ruaBusca).isEmpty()){ultimaRuaBusca=ruaBusca;tempoUltimaRuaBusca=System.currentTimeMillis();ruas=bd.obterRuas(estado,cidade,removerTipoDoLogradouro(ruaBusca));}elseruas=newLinkedList<Cep>();}}}//outros métodos getters e setters}
[size=18]é isso aí, este tópico esta aberto para mais sugestões de Aggregation[/size]
Ygor
Boa tarde gilbueno;
Apenas um adendo, creio que não fara diferença nenhuma no resultado do seu código, mas como informação nunca é de mais.
Quando tu regristra uma função nos EventListeners do jsf.ajax
jsf.ajax.addOnEvent(function(data) {
//esta função é executada após o request - estou focando o elemento novamente neste caso
focarNoUltimo();
});
Essa função é chamada tanto no beggin,complete e success da requisição ajax. Se tu quiser que determinada função ocorra apenas em algum estado, a variavel data possui um atributo String chamado status(data.status) que retorna o estado atual da requisição. Ai é só fazer um if (data.status == “success”) {}, muito util quando a gente precisa colocar um gif de load simbolizando um ajaxStatus
gilbueno
nossa muito legal, isso pode ser útil no futuro, por enquanto vou deixar deste jeito
que já esta funcionando, não gosto muito de trabalhar com javascript.
eu posso usar isto mesmo com o f:ajax certo?
Ygor
Sim, pode sim. Na verdade é até bom tomar um pouco de cuidado quando tu cadastra essas funções no eventListener por que elas são chamado em qualque requsição ajax. E como não existe um removeEvent() pode se tornar um pouco complicado. Ai tu tera que trabalhar com o atributo data.source que retorna o objeto no qual a requisição ajax foi feita e apartir disso definir qual comportamento realizar.
Os frameworks(Prime) ja possuem uma solução mais elegante, os componentes possuem eventos oncomplete, e as funções sao chamadas no complete referente a requisição ajax do componente eliminando a necessidade de cadastrar um evento numa lista de eventListeners
ps: quando eu digo qualquer requisição ajax, é qualquer mesma. Qualquer componente que tenha um <f:ajax>, mojarra.ab(). jsf.ajax.request() ira fazer uma chamada a essa função.
gilbueno
é eu percebi este comportamento mesmo. Estou convencido de que é uma boa
idéia usar o primeFaces no próximo projeto que precisar de algo sofisticado em ajax.
economiza muito tempo de trabalho usar um framework com a funcionalidade pronta.
gilbueno
código javascript editado para melhor funcionamento no internetExplorer