How to pass data from one class to another in javascript using addEventListener or observer pattern?

1

I have a web page of a form in which I have some components placed with Bootstrap.

I have a component that is a bar that as I fill in the questions on a form, the bar should grow. For that I have a class made called a bar and another called a form. The bar class must collect the number of questions that are answered form.

The form sends an event to the main page with:

window.parent.postMessage

And I pick it up with:

window.addEventListener ('message', function(e) { // código  });

Is this way of passing data from one class to another correct? Is there any more simple? I have read that it can be done with the observer pattern, but I do not know how it is implemented in javascript

I will add more code to clarify it:

In what is the main page 'pagina.html' where I have the form I have something like this:

window.addEventListener('message', function (e) {
    switch (e.data.tipo) {
      case "FormularioControl":
        barra.goStep(e.data.subTab);
      break;
    }
  });

Where bar and form is an object of a class in javascript that instanced it as

var  barra = new BarraControl();
var formulario = new FormularioControl();

Inside the Form Control class I have a call to a method every time you click on the following button and send a message to the main page.html like this:

window.parent.postMessage({"tipo":"FormularioControl", "subTab": this.currentSubTab }, "*");

Where the key 'type' reflects what class the message comes from, in this case "Control Form" and the variable "subTab" has the value of the step it goes through. According to this value the bar will grow or decrease.

    
asked by Popularfan 31.12.2018 в 19:17
source

1 answer

1

What you are really doing is using the messaging to implement the Observer , which is just allowing other components to know the changes in an Observable class.

If you want to do it without using the events of the messaging API, which are more designed for communication between different pages opened in the same browser, you could implement it with something like:

class FormularioControl {

  constructor() {
    this.observadores = [];
    console.log('Empezamos con', this.observadores.length, 'observadores');
  }
  //... métodos con el código de control del formulario
 
  subscribe(callbackFn) {
    if (typeof callbackFn === 'function') {
    console.log('Añadimos una subscripción');
      this.observadores.push(callbackFn);
    }
  }
  
  notificarObservadores(datos) {
  console.log('Nofiticamos a todos');
    this.observadores.forEach( callbackFn => callbackFn(datos));
  }
  
  simularAvance() {
    for (let i = 0; i < 5; i++) {
      setTimeout(() => {
        this.notificarObservadores({progreso: i*25})
      }, 1500 * i);
    }
  }
  
}

class BarraControl {

  constructor (id) {
    this.progreso = 0;
    this.barra = document.getElementById(id);
  }
  
  actualizarProgreso (p) {
    this.progreso = p;
    this.barra.value = +this.progreso;
    console.log('Progreso Actual:', this.progreso);
    
  }
}

const formulario = new FormularioControl();
const barra = new BarraControl('progreso');
const barra2 = new BarraControl('progreso2');
formulario.subscribe(datos=> barra.actualizarProgreso(datos.progreso));
formulario.subscribe(datos=> barra2.actualizarProgreso(datos.progreso));
formulario.simularAvance();
<progress id="progreso" value="0" max="100">
</progress>

<progress id="progreso2" value="0" max="200">
</progress>
    
answered by 02.01.2019 / 09:50
source