DEV Community

Wanderson Alves Rodrigues
Wanderson Alves Rodrigues

Posted on

4 1

Two-way data binding com JavaScript

Vou mostrar como fazer um two-way data binding sem usar nenhum framework só com Javascript puro.

Two-way data binding, é o termo dado a reatividade dos elementos na sua interface. Ou seja, o que acontece no DOM (View), reflete no JavaScript(Model), e o que acontece no JavaScript(Model), reflete no DOM(View).

Alt Text

No exemplo que vou disponibilizar dois botões um para incrementar o valor e outra para decrementar, qualquer interação com os botões temos a atualização do DOM que é exibida no input e também atualiza o Model no Javascript.

Alt Text

Alt Text

1 - Criar o projeto

Crie uma pasta e nela adicione os arquivos index.js e index.html.

2 - HTML

No HTML temos o seguinte código abaixo:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <!-- CSS only -->
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/css/bootstrap.min.css" rel="stylesheet"
    integrity="sha384-KyZXEAg3QhqLMpG8r+8fhAXLRk2vvoC2f3B09zVXn8CA5QIVfZOJ3BCsw2P0p/We" crossorigin="anonymous">
  <title>Two way data binding</title>
</head>

<body>

  <div class="container py-5">
    <form class="row g-3">
      <div class="col-auto">
        <input min="0" type="number" class="form-control" id="ipt-number" placeholder="Número" disabled>
      </div>
      <div class="col-auto">
        <button type="button" class="btn btn-success mb-3" onclick="increment()">(+)</button>
        <button type="button" class="btn btn-danger mb-3" onclick="decrement()">(-)</button>
      </div>
    </form>
  </div>

  <script src="index.js"></script>
  <!-- JavaScript Bundle with Popper -->
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/js/bootstrap.bundle.min.js"
    integrity="sha384-U1DAWAznBHeqEIlVSCgzq+c9gqGAJn5c/t99JyeKa9xxaYpSvHU5awsuZVVFIhvj" crossorigin="anonymous">
  </script>
</body>

</html>
Enter fullscreen mode Exit fullscreen mode
  • Para a estilização optei por usar o Bootstrap, por isso foi adicionado o CSS e Javascript.

CSS:

  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/css/bootstrap.min.css" rel="stylesheet"
    integrity="sha384-KyZXEAg3QhqLMpG8r+8fhAXLRk2vvoC2f3B09zVXn8CA5QIVfZOJ3BCsw2P0p/We" crossorigin="anonymous">
Enter fullscreen mode Exit fullscreen mode

Javascript:

  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/js/bootstrap.bundle.min.js"
    integrity="sha384-U1DAWAznBHeqEIlVSCgzq+c9gqGAJn5c/t99JyeKa9xxaYpSvHU5awsuZVVFIhvj" crossorigin="anonymous">
Enter fullscreen mode Exit fullscreen mode
  • O código é bem simples pois temos um input disabled que será o alvo das alterações do valor no DOM e dois botões (+) que lança a ação de incrementar e o (-) que lança a ação de decrementar.

  • As ações são disparadas pelo evento onclick de clique em qualquer botão que chama as funções correspondentes;

3 - Javascript

A interação com o DOM encontra-se no Javascript, e nela que vamos usar a propriedade Object.defineProperty para manipular nosso objeto que será atualizado de acordo com o valor do input e por ações podemos atualizar o DOM.

O código pode ser visto abaixo:

const model = {
  value: ""
};

load = () => {
  const number = document.getElementById("ipt-number");
  number.value = "0";

  Object.defineProperty(model, "prop", {
    get: function () {
      console.log("Getter called");
      return this.value;
    },
    set: function (value) {
      console.log("Setter called", value);
      this.value = value;
      printVal();
    }
  });
};

increment = () => {
  let val = parseInt(model.prop || 0) + 1;
  model.prop = val;
};

decrement = () => {
  let val = parseInt(model.prop || 0) - 1;
  if (val < 0) val = 0;
  model.prop = val;
};

printVal = () => {
  const el = document.getElementById("ipt-number");
  el.value = model.prop;
};

load();
Enter fullscreen mode Exit fullscreen mode
  • load: Nessa função temos a inicialização do input com o valor zero e a criação do manipulador do nosso objeto através da propriedade Object.defineProperty;

  • Object.defineProperty: Como primeiro parâmetro definimos o objeto que será definida as propriedades, depois a propriedade que será definida ou alterada e por ultimo uma função com os métodos get e set. Quando queremos atualizar o objeto model usamos o set e para obter o valor atual usamos o get;

  • increment: Nessa função é a ação de incrementa o valor do objeto model, pegamos o valor atual model.prop e depois de executar alguma regra no caso uma soma com 1 atualizamos o nosso objeto model model.prop = val com o novo valor;

  • decrement: Nessa função é a ação que decrementa o valor do objeto model, então pegamos o valor atual do model, pegamos o valor atual model.prop e depois de executar alguma regra no caso o valor atual menos 1 atualizamos o nosso objeto model model.prop = val com o novo valor;

  • printVal: Nessa função para cada ação de incrementar ou decrementar o método set é disparado para atualizar o DOM;

O código pode ser obtido no Github.

Image of Datadog

The Future of AI, LLMs, and Observability on Google Cloud

Datadog sat down with Google’s Director of AI to discuss the current and future states of AI, ML, and LLMs on Google Cloud. Discover 7 key insights for technical leaders, covering everything from upskilling teams to observability best practices

Learn More

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more