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 on all click on the map adds a marker.
Well the problem is in controlling the states, I tried to come up with some solution, I went after tutorials, libraries like React and/ or frameworks like angular 1, 2, also falls into a frame work called Choo but in the end I did not reach any conclusion, I just got more confused on how to do.
MY SOLUTION
To begin with, I will present my first attempt to ' solution' 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 be executed correctly, but this would result in a lot of other functions resulting from each object, such as: test.estadoatual.render(), test.estadoatual.deleteRender() and so on, with this amount of functions it’s all 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>
<div id='bt1' class='bt'></div>
<div id='bt2' class='bt'></div>
The above code works somehow ... well, the red button runs the log, and the blue change status, but I can’t verify which state it is to prevent the user from being "spammed" the button and the app bugges, which would be bad, in which case it doesn’t happen but when it receives a command from a button that is contained in another window, the user can simply keep pressing and re-starting the code.
DOUBTS
EDIT: The questions, are in a way individual, I do not know if something like this is allowed, but if you have the answer to any of them, please share with us
- How can I check the status in the second example? Something similar to checking the first solution. <<< SOLVED (READ REPLY AND EDITS).
- Are there alternatives to this design? If so, which ones do you know and which ones you recommend?
- With my research, I saw that frameworks as angular and Choo deal with the state of the application, there are more alternatives to them?
- What is the advantage of using frameworks instead of the method I’m using?
- React also handles states, but what difference do they make to angular or Choo?
BIBLIOGRAPHY
Tutorial state Pattern: http://robdodson.me/take-control-of-your-app-with-the-javascript-state-patten/
Choo: https://github.com/yoshuawuyts/choo
Angular: https://angular.io/
React: https://facebook.github.io/react/
Electron:http://electron.atom.io/
EDITS
After a little more effort, I came to an answer that reacts as I wish, follows the answer:
function machine() {
const self = this;
this.estadoatual = undefined;
let estadoatual = undefined;
let estados = [];
this.addstate = (obj) => {
estados.push(obj);
console.log('[STATE_MACHINE]> '+ obj.name + ' <added to states!');
};
this.changestate = (string) => {
for(var i in estados) {
if(string == estados[i].name) {
console.log('[STATE_MACHINE] Found: ' + estados[i].name);
if(string !== estadoatual){
console.log('[STATE_MACHINE] State changed to: ' + estados[i].name + '.');
estadoatual = estados[i].name;
self.estadoatual = new estados[i].constructor;
}
}
}
}
}
const sm = new machine();
//Note que o objeto leva somente dois parametros, na função construtora, pode se escrever o que desejar.
sm.addstate({name:'nome', constructor: function(){
console.log('teste');
}});
sm.changestate('nome');
This theme is very interesting but your question is 4 in 1 and so it is difficult to answer... Can you "break it" in different questions? Or one after the other to have a sequel maybe...
– Sergio
Well... the sequence would be more or less the one in the doubt part :P but I can try to define them better
– Joao Scheuermann
thanks :P I am a good days behind the answer...
– Joao Scheuermann
Hi Joao. Can you post your answer below, in the area of answers? It became strange to have the answer as part of the question.
– bfavaretto
after I finish making some adjustments I put yes
– Joao Scheuermann
@Don’t forget to put the answer below :)
– Sergio