6 maneiras de fazer a mesma coisa, o que é considerado boas práticas?

As vezes tem tantas maneiras diferentes de fazer o mesmo código que nós ficamos na dúvida quanto a qual maneira usar. O que seria considerado "boa prática" pela comunidade e o que sua equipe entenderia melhor. Suponhamos que você esteja trabalhando dentro de um método de um Domain Service chamado UmDomainServiceChique(objetoDoDominio) que será chamado por uma API. Você tem uma regra de negócio chique para ser verificada que por enquanto chamarei de VerificaMinhaRegraChiqueComplexa(). Você chama UmDomainServiceChique(objetoDoDominio) e caso VerificaMinhaRegraChiqueComplexa() retorne true você vai querer que UmDomainServiceChique faça o que tem que fazer e a api retornar Ok 200, caso contrário você quer que a API responda um erro qualquer, tipo BadRequest, e retornar uma mensagem dizendo que VerificaMinhaRegraChiqueComplexa deu ruim. Eu vejo 6 maneiras de fazer isso, gostaria de saber a opinião de outrs devs sobre qual seria a maneira menos gambiarr...

Evitar duplo submit com jQuery

No trabalho hoje me deparei com a necessidade de impedir que se façam múltiplos submits em uma página Web.

Na empresa onde trabalho não usamos asp.net MVC ou Web Forms, mas sim um framework próprio da empresa, feito sobre asp.net, que lembra muito o asp clássico.

Independente do ambiente ou framework, de ser em php, .net etc, se não houver um recurso nativo para evitar isso então você deve se preocupar: lentidão para enviar a página e o usuário com "dedinho nervoso" clicando em enviar mil vezes por segundo, levando a múltiplos posts (submits) e a inserir mútiplos dados idênticos no seu banco de dados.

Além do trabalho server-side, de validação, prevenção de duplicidades na camada de persistência, redirect para uma página de sucesso etc, deve haver alguma coisa client-side para prevenir o submit duplo.

Com javascript é possível desabilitar o botão no momento do click, e evitar que ele seja pressionado novamente.
Se for um Button do tipo AspButton (System.Web.UI.WebControls.Button), da paleta Web do Visual Studio, num ambiente Web Forms, talvez você deseje adicionar o script como um atributo do botão, no evento load da página.

Com jQuery fica muito fácil, e funciona de uma vez para todas as forms e botões de uma página.

De todos os scripts que eu fucei o desse site http://thepugautomatic.com/2008/07/jquery-double-submission/ me pareceu o melhor. Ele praticamente cria uma função nova no jQuery, que você pode reusar em todas as páginas com uma linha de código.



//isso você coloca em um arquivo js externo, a ser chamado depois do jquery, ou na tag script de uma página
            jQuery.fn.preventDoubleSubmit = function() {
              jQuery(this).submit(function() {
                if (this.beenSubmitted)
                  return false;
                else
                  this.beenSubmitted = true;
              });
            };

//isso você coloca dentro do $(document).ready
    $(document).ready(function() 
    { 
      jQuery('form').preventDoubleSubmit(); 
    }


E está pronto: só de incluir essa pequena linha já resolve todos os problemas de dedo nervoso nas suas páginas.

Tentei também outros scripts, e o script abaixo também funcionou muito bem, embora peque quanto à elegância e ao reaproveitamento de código:

//esse embora diferente, faz a mesma coisa que o script acima: atua na interceptação do submit da form, mas desabilita os botões logo após o submit
$('form').submit(function() {
                if(typeof jQuery.data(this, "disabledOnSubmit") == 'undefined') {
                    jQuery.data(this, "disabledOnSubmit", { submited: true });
                    $('input[type=submit], input[type=button]', this).each(function() {
                        $(this).attr("disabled", "disabled");
                  });
                  //$('input[type=submit], input[type=button]', this).attr("disabled", "disabled");
                  return true;
            }
            else
            {
                return false;
            }
});

Esse terceiro script não funcionou muito bem, não sei explicar porque, mas ele deveria atuar no evento click, sumindo com o botão (ou desabilidando-o) logo o clique aconteça.

//esse atua de forma diferente: tenta interceptar o click
            $('input[type=submit], input[type=button]').live('click', function(){
               
                if(!$(this).prop("disabled"))
                {
                    $('input[type=submit], input[type=button]', this).each(function() {
                        $(this).attr("disabled", "disabled");
                    });
                    
                    //$('input[type=submit], input[type=button]', this).attr("disabled", "disabled");

                    return true;
                }
                else
                {
                    return false;
                }
            });

Uma coisa que  o primeiro script não faz é desabilitar ou esconder os botões, mas basta adicionar a linha $('input[type=submit], input[type=button]', this).attr("disabled", "disabled") para fazer isso. Detalhe que em ambos os scripts eu deixei essa linha comentada. É que as linhas acima já fazem isso varrendo todos os resultados do seletor com um .each(), onde eu posso aproveitar para colocar mais comportamento nesse código.

No seletor, estou passando  thi como contexto, como visto na linha acima. Não sei porque, se omitir isso, não conseguimos fazer sequer uma submissão.

Fique atento, no jQuery, à diferença entre .prop e .attr, explicarei isso num próximo post.

Comentários

Postar um comentário

Postagens mais visitadas deste blog

Botão Add This para adicionar seu post em qualquer rede

Busca de CEP com o Lazarus - Parte 1 - UrlEncode

Uso de memória no SQL Server