Entendendo o JQuery ready() e live()    

Quando estamos aprendendo JQuery, a primeira coisa que aprendemos é que todo código de inicialização é colocado no método ready, porém, muitas vezes não nos perguntamos o porque isso é feito dessa forma.

Quem nunca viu um navegador lento renderizar a página toda torta e depois de alguns segundos sumir com tudo, deixando tudo organizado?

Com certeza isso é devido à má utilização do método ready(), ou desconhecimento do método live().

JQuery.ready(), como funciona?

Muitos pensam que o ready é executado quando a página é carregada por completo, porém, esse pensamento não está certo.

O JavaScript tem nativamente um método que é executado quando a página está carregada por completo, e esse método é o window.onload, que muitas vezes utilizamos na tag body através do evento onload. O método ready do JQuery não substitui esse método, e nem executa no mesmo instante.

Para o navegador a página está totalmente carregada quando todos os recursos da página estão carregados, e isso inclui todos os arquivos externos, como scripts, música e imagens. Apenas quando todos os recursos estão carregados o navegador invoca o evento Load da janela, ou seja, caso a página esteja carregando um script ou uma imagem muito grande, dependendo do navegador, toda a página pode ser exibida, porém, o Load pode não ser chamado ainda. (Obs.: Dependendo do navegador porque existem alguns navegadores que só exibem a página quando todos os recursos da página estão carregados em memória).

Diferente do Onload, o ready executa quando a estrutura do documento está pronta, ou seja, quando o DOM foi carregado por inteiro, mesmo que os recursos da página, como scripts e imagens, ainda não tenham sido carregados. Isso pode acontecer porque muitos navegadores modernos carregam os recursos de forma assíncrona, ou seja, exibe a página, apenas com CSS e texto, por exemplo, e vai carregando imagens paralelamente, sem impedir que o usuário possa começar a ler o conteúdo da página.

Já aconteceu comigo de utilizar um plugin JQuery que carregava os scripts necessários por demanda, e muitas vezes, ao chamar a criação do plugin no método ready, era retornado o erro O objeto não dá suporte para a propriedade ou método, isso porque o arquivo que continha o plugin que eu tentava chamar ainda não estava carregado. Portanto, se você carrega arquivos de forma dinâmica, o ready não é uma boa opção.

Caso seja realmente interessante carregar scripts dinamicamente, crie métodos com callbacks que indiquem que os arquivos já foram carregados, para ai sim você poder atribuir eventos e plugins aos controles.

JQuery.live(), quando usar?

Agora que já entendemos como funciona o método ready(), podemos conhecer o live().

Imagine que você realmente precise carregar algumas informações assíncronas para criar a tela, por exemplo, as informações para criar tabs carregam de um arquivo de acordo com um script de globalization, que é carregado depois que o navegador identifica a linguagem do browser, ou imagine que alguns trechos do seu HTML serão adicionados/carregados, depois que o DOM já está pronto, e portanto, depois que o ready já executou, ou você não quer correr o risco que um browser renderize o começo da página antes de montar todo o DOM, e o começo da página em vez de exibir suas tabs, exiba uma lista (LI) de palavras, pois o ready não executou ainda e você não pôde ligar os métodos dos plugins.

Essas situações podem acontecer e é aí que você utiliza o live.

O live() gerencia eventos em controles que são dinamicamente adicionados ou removidos de uma página, você pode utilizar a chamada live em controle que nem existem ainda, mas que virão a existir durante a vida da página.

Por exemplo, o código abaixo:

<script type="text/javascript">
$().ready(function () {
        $("input:button").click(function () {
            alert(this.value);
            $("<input value=""+$("input:button").length+"" type="button" />").appendTo("#div");
        });
    });
</script>
<div id="div">
    <input type="button" id="btnClick" value="Botao1" />
    </div>

O código acima, do jeito que está, dentro de um ready, sempre que for clicado no primeiro botão, será exibido um alerta com o value do botão, e adicionará um novo. Porém, ao clicar nos adicionados, nada acontecerá, porque uma vez adicionado evento ao botão na criação do DOM, nada mais vai acontecer, porém, com o método live, os controles adicionados dinamicamente também irão receber o evento.

O código ficaria assim:

 

 

<script type="text/javascript">
$("input:button").live("click",function () {
            alert(this.value);
            $("<input value=""+$("input:button").length+"" type="button" />").appendTo("#div");
        });
</script>
<div id="div">
    <input type="button" id="btnClick" value="Botao1" />
    </div>

Desta forma, sempre que for adicionado um novo controle, o novo controle automaticamente irá receber o evento. Isso pode ser muito útil para controle como grid, por exemplo.

Identificando todas as situações onde o live poderia ser utilizado, poderíamos tirar bastante processamento do ready, o que deixaria o processamento da página muito mais rápido, pois os eventos já seriam adicionados ao controle no momento da criação, não só quando o DOM fosse totalmente criados. Fora que mesmo que fossem criados dinamicamente, como exemplificado acima, os eventos já seriam adicionados, poupando alguma quantidade de código, e deixando o documento menor.

E um detalhe interessante, você pode adicionar vários eventos ao mesmo tempo com o live, apenas separando os nomes dos eventos com espaço, por exemplo:

$("input:button").live("mouseover mouseout",function () {...

Conclusão

Nem tudo que a gente aprende no começo é a melhor coisa a se fazer em todas as situações. Nesse post não consegui abordar todos os prós e contras do live e do ready, mas dando uma estudada melhor na biblioteca do JQuery vamos descobrir muitas coisas interessantes.

Vou voltar a falar mais coisas sobre essa biblioteca incrível nos próximos post, tentando sempre melhorar o conhecimento dos métodos que facilitam nossa vida no JavaScript.

Fica ai a dica!

Abraços e até o próximo post.

30. setembro 2010 04:33 by Frederico | Comments (5) | Permalink

O que são Lambda Expressions?    

Lambda Expression para muitos pode ser um assunto simples, uma pratica simples, porém, sempre que começo a usá-las em meu código, vejo muitas interrogações nas pessoas em minha volta, e participando do TechEd neste ano, pude perceber que isso é muito comum, porque quando estava saindo de uma palestra do Otavio Pecego Coelho, sobre paralelismo, ouvi muitas pessoas comentando: “Putz, muito louco, mas quando começa a entrar um monte de ‘Lambda’ começa a ficar meio complicado.” .Bom, não sei como isso pode ser possível, visto que Lambda Expression só veio para facilitar, como veremos ao longo desse post.

Pensando nisso, e conversando com um amigo meu, ele me deu a sugestão de escrever sobre isso aqui, e lá vai. Caso tenham dúvidas ou sugestões, please let me know!

Um pouco do histórico

As expressões Lambdas não são uma grande inovação do time do .Net, na realidade, como a maioria das novidades que surgiram entre o .Net 3.0 e 3.5, elas são evoluções naturais dos rumos que a C# vinha tomando desde a sua criação. Vamos ver como isso aconteceu.

Delegates

Delegate é o princípio de tudo. Delegate resumidamente é um tipo por referência, que armazena ponteiros para métodos. Com a criação de uma Delegate, você defini a assinatura de um método que pode ser armazenado em uma variável do tipo dessa Delegate, ou seja, os métodos “apontados” nas variáveis de tipo Delegate devem seguir as regras definidas na Delegate.

Podemos usar Delegates para “delegar” a responsabilidade de execução de uma lógica específica a um outro método, que pode ser implementado depois.

A definição de uma delegate é a seguinte:

[modificador] Delegate [tipo de retorno [Nome da Delegate] ([parâmetros de entrada])

public delegate int Conta(int v1,int v2);

Definindo essa Delegate, qualquer método que tenha essa assinatura pode ser delegado a uma variável do tipo Conta. Os eventos basicamente utilizam Delegates para definir qual deve ser a assinatura de um método que implementa um evento. A Delegate do evento basicamente é a seguinte:

public delegate void Evento(object sender, EventArgs args)

E como podemos utilizar? O exemplo padrão sempre é o da calculadora. Imagina que queiramos delegar ao usuário a opção de escolher qual operação ele deseja executar. Vamos criar dois método, Somar e Subtrair. O código completo de uma aplicação console está abaixo:

    delegate int Conta(int v1,int v2);
    class Program
    {
        static int Soma(int valor1, int valor2)
        {
            return valor1 + valor2;
        }
        static int Subtrair(int valor1, int valor2)
        {
            return valor1 + valor2;
        }

        static void Main(string[] args)
        {
            Console.Write("Valor 1:");
            var v1 = Console.ReadLine();
            Console.Write("Valor 2:");
            var v2 = Console.ReadLine();
            Console.Write("Operação(+ ou -):");
            var op = Console.ReadLine();

            //Operação padrão é soma
            Conta operacao = Soma;

            switch (op)
            {
                case "+":
                    operacao = Soma;
                    break;
                case "-":
                    operacao = Subtrair;
                    break;
            }

            //Chamo o método que o usuário selecionou, sem me importar qual é
            var ret = operacao(Convert.ToInt32(v1), Convert.ToInt32(v2));

            Console.WriteLine("Resultado: {0}", ret);
            Console.ReadKey();
        }
    }

Assim estamos delegando ao usuário qual método utilizar. Com esse entendimento, podemos já perceber, como a equipe do C# percebeu, vários momentos onde utilizar ponteiros de métodos por parâmetro.

Obs.: Como Delegate obriga a implementação de uma assinatura, por isso os tipos e a quantidade de parâmetros são importantes, porém não o nome dos parâmetros.

Em Collections podemos ver o uso desta técnica em muitos métodos, por exemplo, o Sort, Find, etc. A equipe do .Net teve o segundo dialogo (obviamente o dialogo seguinte é inventado):

“Por que não podemos ter um Collection qualquer, e deixar que o programador se preocupe em como ordenar? “

“Sim, e para isso ele passa por parâmetro o método, desde que ele implemente a assinatura, respeitando uma Delegate”

Certo, então da mesma forma que podemos criar variáveis de tipos de Delegate, podemos utilizar parâmetros de tipos Delegate. Por exemplo, para utilizar o método Find, implementamos uma Delegate chamada Predicate, inclusive a utilização dos métodos de Collection são de predicados por esse motivo.

public delegate bool Predicate(T obj);

Onde T é o tipo da sua lista, ou seja, uma lista List<int> o T seria int. A implementação do método abaixo seria a seguinte:

	static bool Buscar(int valor)
        {
            return valor == 1;
        }

Sua chamada seria a seguinte:

           List<int> lista = new List<int>();
            //alimenta a lista
            
            var itemEncontrado = lista.Find(Buscar);

Certo, com isso entendemos como funciona uma Delegate, então vamos evoluir até chegar a Lambda Expression.

Métodos Anônimos

A equipe do C# percebeu que a adoção de Delegates era muito boa, porém, é um tanto trabalhosa, pois você precisa criar métodos sempre que precisar utilizar Delegate, o que te faz ter que digitar mais, e o seu código pode ficar mais confuso.

Imagine que você precisa realizar a busca citada acima apenas em um trecho especifico de código, você teria a necessidade de criar um método, mesmo que sua utilização fosse extremamente restrita, e o pessoal da Microsoft pensou: “Por que não criarmos apenas o código do método, e não o método em si? Ficaria mais simples e mais rápido”.

Ótimo idéia, e assim entra o método anônimo no jogo.

Métodos anônimos são métodos, como o próprio nome diz, sem nomes. São métodos criados dentro de outros métodos, adicionando seu conteúdo diretamente em uma variável ou parâmetro do tipo Delegate.

Por exemplo, em vez de criarmos o método Busca acima, poderíamos colocar o seu código diretamente na chamada do método:

	var item = lista.Find(delegate (int valor){
                return valor == 1;
            });

O resultado seria o mesmo, com a diferença de não precisarmos criar um novo método na classe. Essa técnica pode ser utilizada em qualquer situação onde usaríamos o método ponteiro para a Delegate, ou seja, variáveis, parâmetros, eventos, etc.

Finalmente Lambda Expression

Bom, diante de tudo que vimos acima, percebemos que codificar “on the fly” dessa forma agiliza muito o processo de desenvolvimento, além de não deixar códigos muito específicos por toda parte da classe.

Mas ai ainda percebemos que digitamos muito além do necessário. Pensa comigo:

“Para que a palavra chave “delegate”? Afinal, eu já sei que é uma delegate.”

“Para que ter que definir o tipo do parâmetro?” Afinal, se o compilador já sabe qual é a Delegate a ser utilizada, logo ele já sabe quais são os os tipos e a quantidade dos parâmetros.”

“E as vezes o método é tão simples, que a única linha já é o retorno, então para que utilizar o return?”

Aí mais uma vez o time do C# deu uma forcinha, dizendo: “Vamos simplificar tudo criando um novo operador que serve para separar os parâmetros do método do corpo do método e pronto!”

E o Find da Collection ficou assim:

var item = lista.Find(valor=>valor == 1);

Agora sim o método ficou sucinto, o que está antes do => (igual maior) são os parâmetros de entrada, e o que está depois é o retorno do método caso tenha só uma linha, ou o corpo do método, caso tenha mais de uma linha.

Se quisermos criar uma Lambda Expression para nossa delegate Conta criada acima, seria o seguinte:

 
operacao  = (valor1, valor2)=> valor1 + valor2;
var ret = operacao(Convert.ToInt32(v1), Convert.ToInt32(v2));

Muito simples! Perceba que para mais de um parâmetro, adicionamos parênteses. Caso o corpo do método seja mais complexo, com mais de uma linha, teremos que utilizar chaves e no final utilizar a palavra chave return.

Conclusão

Neste post vimos como Lambda Expression nada mais é que uma evolução natural das técnicas utilizadas pelo C# desde sua primeira versão.

Por ser uma evolução, isso só pode surgir para ajudar e simplificar nossa vida. Caso não esteja sendo claro em nossas cabeças as evoluções que a linguagem vem tomando, é importante que entendamos o porquê das mudanças.

Muitos já criticaram o “dynamic” do C#, sem ainda entender o porque de se utilizá-lo. Vou tentar abordar isso em um momento oportuno.

Bom, espero que tenham gostado desse post.

Até o próximo!

24. setembro 2010 06:51 by Frederico | Comments (4) | Permalink

DataBind na Web    

Para quem é programador WindowsForm, o conceito de DataBind é comum. Caso você não saiba muito do que estou falando, o conceito é bem simples:

Você define um DataSource em um Formulário, e com isso consegue atrelar um campo da fonte de dado a um campo do Formulário, fazendo que qualquer alteração que aconteça em uma das pontas, reflita na outra.

Isso pode ser muito útil, pois ajuda muito no tempo de desenvolvimento, visto que não é necessário codificar dois códigos, um para atribuir informações da fonte de dados aos campos da tela, e depois o caminho contrário.

Na Web esse tipo de conceito não é muito comum, mesmo que em WebForm você consiga adicionar DataSources a uma página, e utilizar DataBinders nos campos, o conceito é consideravelmente diferente, visto que a direção dos dados é apenas de Fonte de Dados para campos, e o caminho inverso deve ser feito manualmente.

Como adicionar DataBinders na Web

Bom, quem me conhece sabe que dificilmente eu iria  elogiar Windows Forms e criticar a Web desta forma. De fato, na minha opinião, o que a Web ainda tem que não é tão bom é a banda da internet, que é um problema que logo mais será resolvido no mundo. Quanto experiência do usuário, ou experiência de desenvolvimento, cada vez mais eu percebo que a Web não deixa nada a desejar, e tem ficado cada vez melhor, com HTML5, CSS 3, ou mesmo plugins como SilverLight ou Flash.

Mas o que quero falar aqui é da sensação dos últimos anos: JQuery, que pode ser baixada clicando aqui.

JQuery, segundo definição do próprio site, é uma biblioteca JavaScript que simplifica a transformação de HTML, manuseio de eventos da página, animação e interações de Ajax para desenvolvimento rápido para Web. JQuery é projetado para mudar a forma que você escreve JavaScript

Bela definição, e de fato JQuery é uma biblioteca poderosa que ajuda muito a controlar o comportamento de uma página Web. JQuery é uma biblioteca tão popular hoje em dia, que a própria Microsoft teve que abraçar, e agora ela já vem embutida nos projetos web do Visual Studio 2010.

A Microsoft, inclusive, tem incentivado o seu time de desenvolvimento a contribuir com o JQuery, e eles têm feito grandes feitos a pelo menos dois anos.

Hoje vou falar de uma das contribuições: Data Linking

Utilizando JQuery Data Linking para realizar Data Bind na Web

Data Linking é a forma que a Microsoft achou para realizar databing na Web, e o funcionando é extremamente satisfatório. Como no Windows Form, o funcionamento é bidirecional (fonte de dados para campos e vice-versa).

Seu funcionamento é simples, no padrão do JQuery: a partir de um objeto JSON, que pode ser retornado de um PageMethod, nós fazemos os binds com apenas uma linha de código.

Abaixo segue o código de uma página utilizando esse plugin:

 

<pre><script type=" src="jquery-1.4.2.js" javascript?="javascript?" text="text"></script>
<script type="text/javascript" src="jQuery.datalink.js"></script>

    <h2>
        Data Linking
    </h2>
    <p>
        Nome: <input id="txtNome" />
    </p>
    <p>
        Idade: <input id="txtIdade" />
    </p>
    <input id="btnClick" value="Ler" type="button" />
    <input id="btnScript" value="Alterar Via Script" type="button" /></pre>

<script type="text/javascript">

    var pessoa = { Nome: "Frederico", Idade: 24 };

    $("#btnClick").click(ler);

    $("#btnScript").click(function () {
        //Alterando programaticamente
        $(pessoa).attr("Nome", "Frederico Emídio");
    });

    function preencher() {
        //Definindo o bind.
        $(pessoa).linkBoth("Nome", "#txtNome", "val")
                .linkBoth("Idade", "#txtIdade", "val");
    }

    function ler() {
        alert(pessoa.Nome + ' - ' + pessoa.Idade);
    }

    preencher();
</script>

Os três parâmetros do método linkBoth são óbvios: Nome da propriedade do DataSource, nome do Controle, e método que deve ser usado para a realização do bind. (Obs.: Caso você queira apenas o bind na direção da fonte de dados para os controles, você poderia usar o método linkFrom, utilizando os mesmos parâmetros).

O resultado da página pode ser visto aqui. Neste exemplo você pode ver que as alterações, tanto feitas no código como nos campos são refletidas em ambos os locais.

Uma outra função também existe neste plugin, que é a de formatação das informações ao atribuir os valores nos campos, mas para o intuito deste post, o que foi mostrado já é o suficiente.

Clique aqui para baixar o plugin Data Link “beta”

Até o próximo post!


  
     
  
14. setembro 2010 09:50 by Frederico | Comments (1) | Permalink

Sobre mim

Minha Imagem

Meu nome é Frederico Batista Emídio, trabalho com desenvolvimento de sistemas profissionalmente a oito anos, porém, já faço sites pessoais a pelo menos dez anos.

Para saber mais clique aqui.

Páginas

Calendário

<<  novembro 2017  >>
seteququsedo
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

Visualizar posts em um Calendário
Sigua @fredemidio

MCP Asp.NET