Prototype Ajax Bind e Outras ‘Futilidades’

5 03 2008

Saudações

Hoje precisei fazer uma interface para um de nossos sistemas que devido a quantidade monstruosa de chamas em AJAX que ao olhar para o meu firebug achei que estava usando o Gtalk (outra piadinha de micriro tá loco!), mas enfim com toda essa movimentação cliente servidor e tudo mais surgiram vários problemas, uns novos outros fantasmas antigos e que eu sempre lidava com eles com o meu jeito maroto de programar :), mas eis que vamos ao primeiro problema do dia, o BIND.

Aqui vai uma história, lá nos idos de 2006 eu um jovem acadêmico do Curso de Informática da Unioeste, que por sinal é muito bom, freqüentava as aulas de LP (Linguagem de Programação), existe um fato curioso sobre o curso de Informática, os nomes das matérias muitas vezes não refletem o que é visto em sala de aula, o primeiro exemplo é essa ai LP se você acha que vai aprender a programar na aula de linguagem de programação esta redondamente, triangularmente para não dizer quadraticamente enganado, na aula de LP você conhece as estruturas da sintaxe, semântica e BNF das linguagens é quase uma aula de gramática porém de linguagem de programação, legal né, uma outra matéria que vai nessa mesma linha de raciocínio (não linear) é a aula de SA (Sistemas Administrativos) se você acha que vai ver Livros Caixa, Cartão Ponto, ou seja, Sistemas Administrativos de uma empresa caiu do cavalo, ali você vai ter uma sopa de letrinhas, que vai desde os GED aos SAP coisa estranha né, mas voltando a aula de LP, um belo dia o Bidarra, um carioca que dava aula dessa disciplina veio com uns papo de BIND, até que uma bela hora eu saquei o que ele falava, o tal do BIND era o escopo das variáveis, ai eu falei – O Prof esse tal de BIND ai não é o escopo, ai ele falo – Sim, fiquei muito macho rapaz porque não falo logo de cara que era sobre escopo, mas enfim, depois de muitos anos me deparo com o tal do BIND na vida real e o que é mais loco ainda, em javascript uma linguagem que eu sempre juei e que hoje é uma das que mais programo, mundo louco né!

Quando você faz uma chamada em ajax usando o prototype, exemplo:

var minhaVariavel = 10;
var ajax = new Ajax.Request(
    url,
    {
        onSuccess: function(r){
            minhavariavel = r.ResponseText
        }
    }
);

A variável minhavariavel que está dentro do onSuccess não é a mesma variável minhavariavel que está fora do onSuccess, ou seja, ela possui o mesmo nome mas escopo diferente, porque é normal e natural, prejudica um poouco a legibilidade do código, mas você pode ter duas variável com o mesmo nome com valores diferentes desde que estejam em escopos diferentes, por exemplo uma é local a uma função e outra é global a todo o código fonte, agora e se eu quero que dentro do onSuccess a variável minhavariavel seja aquela de fora, heim heim heim, é fácil mas difícil de achar a solução e eu to fornecendo aqui na faxa, era pia bom só.

var minhaVariavel = 10;
var ajax = new Ajax.Request(
    url,
    {
        onSuccess: function(r){
            this.minhavariavel = r.ResponseText
        }.bind(this)
    }
);

O que você fez foi colocar as duas funções no mesmo escopo, vinculado ela ao this que na verdade é o objeto window do javascript, tudo que está fora de uma função é vinculado ao this, o que aconteceu nesse caso é que o onSuccess esta ligado a variável ajax, percebem isso, e por este motivo para se mudar o escopo do onSuccess é necessário colocar aquele bind(this), levei muito tempo pra descobrir isso, espero que seja útil para alguém.

Algumas referência sobre BIND (não me ajudaram muito mas eu sou meio parvo as vezes :))

http://www.prototypejs.org/api/function/bind
http://faves.com/users/derek/tag/bind/prototype
http://www.sitepoint.com/article/painless-javascript-prototype/2

O segunda problema do dia foi o seguinte, precisava adicionar linhas a uma tabela através do Javascript, até ai nada de novo, mas eu cansei do jeito antigo, document.createElement, e textNode, cansei, pensei comigo: vou achar um jeito mais massa de fazer isso, e achei, usando o interpolate e o insert ambas funções do prototype versão 1.6

$('tabela').insert(
    '<tr><td>#{colunaA}</td><td>#{colunaB}</td></tr>'.interpolate({
        colunaA: vardacolunaA,
        colunaB: vardacolunaB,
    })
);

O insert permite que você escreva um trecho de HTML normal e insira este treco dentro de um outro elemento HTML, você pode usar o innerHTML para fazer isso porém a W3C depreciou o innerHTML e nas próximas versões do Javascript ele estará fora, então melhor aprender a viver sem ele, eu gostava tanto dele :(.

O interpolate funciona como o sprintf do PHP, você cria uma string com tags e passa as variáveis que vão ocupar o destas tags depois da interpretação, a ordem não importa porque como viram no exemplo é preciso colocar o nome da tag o que não acontece como sprintf que em que a ordem das tags define a ordem da inserção das variáveis.

E para fechar o post do dia quero deixar aqui uma última dica para que esta começando no ajax e usando o prototype, muitas vezes você vai fazer uma chamada ao servidor para confirmar alguma coisa, por exemplo passa para o servidor um código e recebe de volta o nome de alguém por exemplo, agora imaginem que a execução do seu Javascript depende do retorno do servidor, você quer escrever o nome do cidadão na tela por exemplo, o AJAX é assincrono ou seja você executa o AJAX e o Javascript vai em borra e continua sendo executado não espera ninguém, metido né, uma solução é dizer para o prototype que a sua chamada em Ajax na verdade não é assíncrona, ou seja é só o jax o pior é se você não retornar um XML ai você está fazendo só um ja, (outra piada de micreiro), isso força o Javascript a esperar que o retorno chegue do servidor para enfim seguir seu caminho para o ; (ponto-e-vírgula) final da jornada, e como fazer isso simples pequeno gafanhoto (como diria o mestre miyagi, que Deus o tenha em um ring cheio de Karatecas maus só pro velhinho zuar) !

var minhaVariavel = 10;
var ajax = new Ajax.Request(
    url,
    {
        asynchronous : false
        onSuccess: function(r){
            this.minhavariavel = r.ResponseText
        }.bind(this)
    }
);

Bom por hoje é só fiquem com Deus e até a próxima, no meu no seu no nosso battisti.wordpress.com CRUJ CRUJ CRUJ Tchau, lembram desse? recordar é viver 🙂


Ações

Information

2 responses

9 03 2008
Marcelo Carlos

Sério o lance de acabar com o innerHTML? poxa, vou sentir saudades… Quem vai substituí-lo?

9 03 2008
battisti

Então Marcelo o problema com o innerHTML é que ele não está nos padrões da w3c e provavelmente nunca entrará pois a w3c preconiza o uso do DOM para fazer o trabalho que o innerHTML faz, aqui tem alguns links que falam sobre o assunto,

http://www.bestcodingpractices.com/break_your_innerhtml_addiction-2719.html

outro bem interessante é esse feito pela mozilla,
http://developer.mozilla.org/en/docs/DOM:element.innerHTML

da uma olhada lá no Specification. Se bem que com os novos Frameworks (prototype, mootol, jquery, ext e por ai vai) ficou fácil manipular o DOM e o innerHTML ficou meio que obsoleto.

Deixe um comentário