Alternating states of an application js

4

INTRODUCTION

I'm developing an app using Electron and google maps, I need to control the state of one of the windows, for example: the user clicks the button and from this moment every click of the map adds a marker.

Well the problem is in controlling the states, tried to come up with some solution, went behind tutorials, libraries as react and / or frameworks as angular 1, 2, also falls into a frame work called Choo but in the end not I reached the conclusion, I was only more confused in how to do.

MY SOLUTION

To begin with, I'll introduce my first 'solution' attempt based on this > TUTORIAL , in which I made some changes.

function machine () {
  this.estadoatual = undefined;
  const estados = {
    estado1:  {
      log:() => {console.log('teste')}
      /*funçoes e comandos do estado*/
    },
    estado2:  {
      log:() => {console.log('teste2')}
      /*funçoes e comandos do estado*/
    }
    /*...*/
  };

  this.changeState = (string) => {
    //verifica a string e o estado atual
    if ( string == 'estado1' && this.estadoatual !== estados.estado1) {
      this.estadoatual = estados.estado1;
    }
    //verifica a string e o estado atual
    if ( string == 'estado2' && this.estadoatual !== estados.estado2) {
      this.estadoatual = estados.estado2;
    }
  }
  
  
}

const teste = new machine();

/* por favor abra o console :P */
teste.changeState('estado1');
teste.estadoatual.log();
teste.changeState('estado2');
teste.estadoatual.log();

In this solution all states would have to have the same properties to run correctly, but this would result in a lot of other functions resulting from each object, such as: test.status, current.test (), test.status. deleteRender () and so on, with this amount of functions everything is more confusing.

I thought of a second solution to my problem:

function machine () {
  this.estadoatual = undefined; 
  const self = this;
  
  function estado1 () {    
    console.log('executou o estado1');
    function log () {console.log('click estado1')};// função chamada no evento de click bt1    
    $('#bt1').bind('click', log);
    $('#bt2').bind('click', (event) => {
    self.changestate('estado2');
    $('#bt1').unbind('click', log);
    $(this).unbind(event);  
    })
    this.log = () => {console.log('estado1')}; 
  }
  
  function estado2 () {
    console.log('executou o estado2');
    function log () {console.log('click estado2')};// função chamada no evento de click bt1    
    $('#bt1').bind('click', log);
    $('#bt2').bind('click', (event) => {
    self.changestate('estado1');
    $('#bt1').unbind('click', log);
    $(this).unbind(event);  
    })
    this.log = () => {console.log('estado2')}; 
  }  
  
  this.changestate = (string) => {
   if(string == 'estado1')  { 
/* neste caso não sei como fazer a verificação para não reiniciar o valor do 'estadoatual' quando o usuario clicar de novo*/
     this.estadoatual = new estado1();     
     }
      if(string == 'estado2')  {
/* neste caso não sei como fazer a verificação para não reiniciar o valor do 'estadoatual' quando o usuario clicar de novo*/
     this.estadoatual = new estado2();       
     }
  }
}

const teste = new machine();

//Inicializa o app no estado1
//neste caso ele é quase todo contido em si , não necessitando de chamadas externas, mas também não descartando elas.
teste.changestate('estado1');
//consigo chamar funções que podem ser acessadas fora do escopo da função.
teste.estadoatual.log();
.bt{
height: 30px;
 width: 50px;  
}

#bt1{
background-color: red;
}


#bt2{
background-color: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><divid='bt1'class='bt'></div><divid='bt2'class='bt'></div>

Thecodeaboveworksinaway...well,theredbuttonexecutesthelog,andbluechangesstate,butIcannotseewhatstatusitisinordertopreventtheuserfrom"spamming" the button and the app bugue, which would be very bad, in which case this does not happen but when it receives a command from a button that is contained in another window, the user can simply keep pressing and re-initiating the code.

Doubts

EDIT: the questions are somewhat individual, I do not know if something like this is allowed, but if you have the answer for some of them, please share with us

  • How can I check the status in the second example? Something similar to checking the first solution.
  • asked by anonymous 29.06.2016 / 21:43

    1 answer

    0

    ANSWER:

    After some effort, I came to a definitive answer, now I also know that there are many other ways to get to that result and ways to modify my code to work in other ways, with hooks for every transition or something.

    But direct the answer.

    // STATE MACHINE
    function machine() {
        const self = this;
    
        let ea = undefined;
        let estadoatual = undefined;
        let estados = [];
    
        //Adiciona um estado se não houver um com mesmo nome
        function addstate(obj) {
            let found_state = false;
            for (var i in estados) {
                if (estados[i].name == obj.name) {
                    found_state = true;
                    //console.warn('[STATE_MACHINE] You already have ${obj.name} state stored');
                    return
                }
            }
            if (found_state == false) {
                estados.push(obj);
                //console.log('[STATE_MACHINE]> ${obj.name} <added to states!');
            }
        }
    
    
        this.addstate = (obj) => {
            addstate(obj);
        };
        
        //Troca o estado e chama as funçoes onChange quando mudar de estado e onOpen quando entrar em um estado.
        function changeState(string) {
            for (var i in estados) {
                if (string == estados[i].name) {
                    //console.log('[STATE_MACHINE] Found: ${estados[i].name}');
                    if (string !== estadoatual) {
                        if (ea !== undefined) {
                            ea.onChange();
                        }
                        //console.log('[STATE_MACHINE] State changed to: ' + estados[i].name + '.');
                        estadoatual = estados[i].name;
                        ea = new estados[i].constructor();
                        ea.onOpen()
                    }
                }
            }
        }
    
        this.changestate = (string, param) => {
            changeState(string, param);
        }
    
    }

    Basically we have two methods, "addstate" and "changestate", when calling the addstate, you will have to pass an object containing the 'name' method and one containing a constructor function, , onOpen and onChange, which will be called respectively when a state is opened or when it is changed. Here is an example of initializing the code.

    const sm = new machine();
    
    //Note que o objeto leva somente dois parametros, na função construtora, deve-se passar os parametros onOpen e onChange...
    
    //Adiciona um estado:
    sm.addstate({name:'FOO', constructor: function(){
      this.onOpen = () => {
        //Codigo para ser executado quando aberto.
      }
      this.onChange = () => {
        //Codigo para ser executado quando for trocado por outro estado.
      }
    }});

    Now that we have created a state machine and added one, just call the sm.changestate ('Foo') method.

    // Faz a troca de estados.
    sm.changestate('FOO');

    With this I got the answer I wanted, the code works asynchronously, not needing an order to be activated just calling the changestate () method. Some of the other questions remain unanswered and I would very much like someone to help me with them ...

        
    28.07.2016 / 05:48