Two way data binding
Como implementar?
Minha caminhada com Javascript é bem breve. Assim como a maioria das pessoas, após aprender o bom e velho Vanilla, procurei um framework que pudesse me ajudar a desenvolver aplicações mais complexas de forma mais ágil.
Após pesquisar um pouco, encontrei o famoso Angular da Google que tinha uma proposta um tanto nova…o conhecido hoje, Two Way Data Binding!
Hmm, mas o que é Two Way Data Binding?
Two Way Data Binding pode parecer um pouco confuso no início, para aqueles que estão acostumados com a forma que Vanilla ou JQuery leva os dados do Javascript para o DOM e do DOM para o Javascript.
Pois bem, a proposta principal do Two Way Data Binding é automatizar esse trafego de dados, de tal forma que o desenvolvedor não precise mais criar handlers no DOM para atualizar o Javascript e vice versa. Assim, quando um valor no DOM mudar, o Javascript responsável por aquele DOM também vai será atualizado com o respectivo valor automaticamente sem precisar adicionar qualquer handler, como por exemplo:
// HTML<input onkeyup=”onChange”>//Javascriptwindow.onChange = function (event){ }
Parece algo complicado, né? Mas na verdade é bem simples de ser implementado. :)
A imagem a baixo é um fluxograma de como funciona a lógica de atualização dos dados com Two Way Data Binding:
A imagem a cima cita duas palavras chaves: View e Model.
Nesse escopo, View seria o DOM e Model seria o Javascript responsável por controlar o fluxo de dados para o DOM.
Maneiro, mas e o código? Cadê?
Depois dessa breve introdução ao conceito dessa tecnologia, chegou a hora implementar nosso próprio Two Way Data Binding! Bora codificar!
Crie um arquivo html com o seguinte conteúdo:
<input my-input=”name”>
Como você pode ver o atributo my-input é um atributo customizado e será usado para manipular os valores de entrada quando digitamos algo no campo input.
Adicione a tag script abaixo do campo input, pois vamos adicionar nosso código js dentro delas (isso é uma má prática, então não faça isso no mundo real).
Dentro da tag script, será preciso buscar o elemento que contém o atributo my-input para que possamos “escutar” os valores que são passados para esse elemento. Adicione o seguinte Javascript:
var model = {};var input = document.querySelector('[my-input]');var modelProperty = input.getAttribute('my-input');input.addEventListener('keyup', function (e) {
model[modelProperty] = e.target.value;
});
O código a cima apenas busca o elemento que contém o atributo my-input e após recuperar sua referência, pega o valor que o atributo contém, que nesse caso é o valor “name” (conforme colocamos no html). Esse valor “name” será a propriedade que será modificada no model, que como podemos ver no Javascript a cima…é apenas um Objeto.
Usaremos o evento keyup para atualizarmos em tempo real o model.
Legal, mas como refletir as alterações do Model no DOM?
Quando estava desenvolvendo o meu próprio Two Way Data Binding, fiquei algum tempo refletindo sobre essa parte.
Afinal, como fazer com que o model saiba quando deve atualizar o DOM?
Depois de um tempo pesquisando, resolvi usar o watch do Javascript que funcionou muito bem para essa necessidade!
Agora que sabemos o que usar para implementar essa necessidade, vamos botar a mão na massa!
Adicione logo abaixo do elemento que contém o my-input, um novo elemento contendo o atributo my-output.
<span my-output="name"></span>
O atributo my-output será o responsável por refletir no DOM as alterações feitas na propriedade “name” do Model.
Agora precisamos adicionar o código Javascript responsável por assistir o model e alterar o DOM quando algo mudar.
var output = document.querySelector('[my-output]'); var modelProperty = output.getAttribute('my-output'); model.watch(modelProperty, function (prop, oldValue, value) {
output.innerHTML = value;
});
Como se pode ver no código a cima, a única coisa que mudou foi a utilização do método watch, que rodará o callback cada vez que a propriedade “name” do Model mudar seu valor.
Agora cada vez que você digitar algo no elemento contendo o atributo my-input, o mesmo valor será refletido no html do elemento contendo o atributo my-output!
É só isso?!
Sim, realmente é bem simples implementar um Two Way Data Binding. Lógico que esse código criado pode ser melhorado e muito! Mas o foco aqui, é manter a simplicidade para o entendimento geral de como as coisas funcionam.
No meu Github contém o repositório com esse tutorial simplificado e refatorado caso seja útil para algo.
Recomende isso para mais alguém, se você gostou. É sempre bom compartilhar conhecimento!
Muito obrigado e por hoje é isso :)