How to Implement DOM Data Binding in JavaScript

Tahseen Tauseef Feb 02, 2024
  1. One-Way Data Binding in JavaScript
  2. Limited Two-Way Data Binding in JavaScript
  3. Better Two-Way Data Binding in JavaScript
How to Implement DOM Data Binding in JavaScript

Data binding is as crucial to current applications as addition is to mathematics. It would seem insane to create any significant application without it.

The Model-View-Controller pattern, connected to data binding, is one of the most fundamental architectural patterns that has given hundreds of offspring.

This article discusses data binding in JavaScript, and different methods are shared with you.

One-Way Data Binding in JavaScript

Many of the motives for the JavaScript frameworks that exist arise from perceived shortcomings in JavaScript, of which there were many. However, as a language, JavaScript has grown to the point where the necessity for frameworks has been significantly reduced.

The notion of data binding is pretty basic. There is a data model on one side, and on the other, there is an interface, often known as a view.

The aim is to “bind” some data to something on the view so that as the data changes, so does the view. This is common with read-only data.

Only when the model and the view change does one-way data binding occur.

Despite appearing to be the simplest, one-way data binding is likely the most difficult to accomplish since it necessitates hooking into JavaScript getters and setters for properties. Object.defineProperty has been around for a long time in JavaScript.

This method enables developers to build custom getters and setters for an object and replace existing ones. For example, this function is used in the following code to alter the getter and setter for a previously specified property.

function Binding(b) {
  _this = this this.element = b.element this.value =
      b.object[b.property] this.attribute = b.attribute this.valueGetter =
          function() {
        return _this.value;
      } this.valueSetter =
              function(val) {
        _this.value = val
        _this.element[_this.attribute] = val
      }

              Object.defineProperty(
                  b.object, b.property,
                  {get: this.valueGetter, set: this.valueSetter});
  b.object[b.property] = this.value;

  this.element[this.attribute] = this.value
}

Take a look at the code: it creates a shadow property to store the value in the Binding object and then uses defineProperty to set the getter and setter for the property. The setter method will now be called anytime the property is set using the equals symbol (=).

Finally, the function will set the property and the DOM element to the specified value. You can see the working of this code through this link.

Limited Two-Way Data Binding in JavaScript

When the view or model is changed, two-way data binding occurs. A two-way binding may be built up using the same basic code.

The binding requires an event to listen for to receive DOM feedback. Take note of where the function addEventListener is invoked.

This adds an event listener to the passed-in element. The event handler will set the shadow copy of the object value data-bound to the element whenever the event is invoked.

Changes to the model will also result in an update to the DOM element.

function Binding(b) {
  _this = this this.element = b.element this.value =
      b.object[b.property] this.attribute = b.attribute this.valueGetter =
          function() {
        return _this.value;
      } this.valueSetter =
              function(val) {
        _this.value = val
        _this.element[_this.attribute] = val
      }

  if (b.event) {
    this.element.addEventListener(b.event, function(event) {
      _this.value = _this.element[_this.attribute]
    })
  }

  Object.defineProperty(
      b.object, b.property, {get: this.valueGetter, set: this.valueSetter});
  b.object[b.property] = this.value;

  this.element[this.attribute] = this.value
}

You can see the working of this code through this link.

However, this code is relatively restrictive in that it only allows for a single one-way or two-way data binding for the element and attribute.

Better Two-Way Data Binding in JavaScript

Allowing a property to be tied to one or more items is a better approach to two-way data binding. This implies that when the value changes, either when a DOM event is called or the model changes, the data binding can update numerous items on the DOM.

Also, take note of the newly introduced addBinding method. This now enables the addition of new components to the binding with events.

These are added to the array elementBindings. The setter method iterates across the elementBindings array when a new value is set and modifies the property.

It may also be used to create one-way data bindings by missing the event option when executing addBinding.

function Binding(b) {
  _this = this this.elementBindings = [] this.value =
      b.object[b.property] this.valueGetter =
          function() {
        return _this.value;
      } this.valueSetter =
              function(val) {
        _this.value = val
        for (var i = 0; i < _this.elementBindings.length; i++) {
          var binding = _this.elementBindings[i]
          binding.element[binding.attribute] = val
        }
      } this.addBinding =
                  function(element, attribute, event) {
        var binding = { element: element, attribute: attribute } if (event) {
          element.addEventListener(event, function(event) {
            _this.valueSetter(element[attribute]);
          })
          binding.event = event
        }
        this.elementBindings.push(binding)
        element[attribute] = _this.value
        return _this
      }

                  Object.defineProperty(
                      b.object, b.property,
                      {get: this.valueGetter, set: this.valueSetter});

  b.object[b.property] = this.value;
}

You can see the working of this code through this link.

This implementation is better, but there is still much work to do. For example, there is no data validation, templating, no array support, no custom UI setters or UI formatters, and a slew of other limitations.

When you combine all of this, the term “framework” begins to form, and there are many of them out there. However, a simple script like this is even more than enough to handle what you need for data binding for many of your needs.

Related Article - JavaScript DOM