Implementar enlace de datos DOM en JavaScript

Tahseen Tauseef 12 octubre 2023
  1. Enlace de datos unidireccional en JavaScript
  2. Enlace de datos bidireccional limitado en JavaScript
  3. Mejor enlace de datos bidireccional en JavaScript
Implementar enlace de datos DOM en JavaScript

El enlace de datos es tan crucial para las aplicaciones actuales como lo es la suma para las matemáticas. Parecería una locura crear cualquier aplicación significativa sin ella.

El patrón Modelo-Vista-Controlador, conectado al enlace de datos, es uno de los patrones arquitectónicos más fundamentales que ha dado cientos de descendientes.

Este artículo analiza el enlace de datos en JavaScript y se comparten diferentes métodos con usted.

Enlace de datos unidireccional en JavaScript

Muchos de los motivos de los marcos de JavaScript que existen surgen de las deficiencias percibidas en JavaScript, de las cuales había muchas. Sin embargo, como lenguaje, JavaScript ha crecido hasta el punto en que la necesidad de marcos se ha reducido significativamente.

La noción de enlace de datos es bastante básica. Hay un modelo de datos en un lado y en el otro hay una interfaz, a menudo conocida como vista.

El objetivo es “vincular” algunos datos a algo en la vista para que, a medida que cambien los datos, también lo haga la vista. Esto es común con los datos de solo lectura.

Solo cuando el modelo y la vista cambian, se produce el enlace de datos unidireccional.

A pesar de parecer el más simple, el enlace de datos unidireccional es probablemente el más difícil de lograr, ya que requiere conectarse a los captadores y definidores de JavaScript para las propiedades. Object.defineProperty existe desde hace mucho tiempo en JavaScript.

Este método permite a los desarrolladores crear captadores y definidores personalizados para un objeto y reemplazar los existentes. Por ejemplo, esta función se usa en el siguiente código para modificar el getter y el setter de una propiedad previamente especificada.

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
}

Eche un vistazo al código: crea una propiedad shadow para almacenar el valor en el objeto Binding y luego usa defineProperty para establecer el getter y setter de la propiedad. Ahora se llamará al método setter cada vez que se establezca la propiedad usando el símbolo de igual (=).

Finalmente, la función establecerá la propiedad y el elemento DOM en el valor especificado. Puede ver el funcionamiento de este código a través de este enlace.

Enlace de datos bidireccional limitado en JavaScript

Cuando se cambia la vista o el modelo, se produce un enlace de datos bidireccional. Se puede construir un enlace bidireccional utilizando el mismo código básico.

El enlace requiere un evento para escuchar para recibir comentarios de DOM. Tome nota de dónde se invoca la función addEventListener.

Esto agrega un detector de eventos al elemento pasado. El controlador de eventos establecerá la instantánea del valor del objeto vinculado a los datos del elemento cada vez que se invoque el evento.

Los cambios en el modelo también darán como resultado una actualización del elemento DOM.

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
}

Puede ver el funcionamiento de este código a través de este enlace.

Sin embargo, este código es relativamente restrictivo ya que solo permite un enlace de datos unidireccional o bidireccional para el elemento y el atributo.

Mejor enlace de datos bidireccional en JavaScript

Permitir que una propiedad se vincule a uno o más elementos es un mejor enfoque para el enlace de datos bidireccional. Esto implica que cuando cambia el valor, ya sea cuando se llama a un evento DOM o cambia el modelo, el enlace de datos puede actualizar numerosos elementos en el DOM.

Además, tome nota del método addBinding recientemente introducido. Esto ahora permite agregar nuevos componentes al enlace con eventos.

Estos se agregan a la matriz elementBindings. El método setter itera a través de la matriz elementBindings cuando se establece un nuevo valor y modifica la propiedad.

También se puede usar para crear enlaces de datos unidireccionales al perder la opción evento al ejecutar 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;
}

Puede ver el funcionamiento de este código a través de este enlace.

Esta implementación es mejor, pero aún queda mucho trabajo por hacer. Por ejemplo, no hay validación de datos, plantillas, soporte de matrices, configuradores de IU personalizados o formateadores de IU, y muchas otras limitaciones.

Cuando combina todo esto, el término “marco” comienza a formarse, y hay muchos de ellos por ahí. Sin embargo, un simple script como este es incluso más que suficiente para manejar lo que necesita para el enlace de datos para muchas de sus necesidades.

Artículo relacionado - JavaScript DOM