Pregunta sobre javascript – En javascript, ¿cómo desencadenar un evento cuando se cambia el valor de una variable? [duplicar]

20

Esta pregunta ya tiene una respuesta aquí:

Escuchando cambios de variables en JavaScript 17 respuestas

Tengo dos variables:

var trafficLightIsGreen = false; 
var someoneIsRunningTheLight = false;

Me gustaría activar un evento cuando las dos variables concuerdan con mis condiciones:

if(trafficLightIsGreen && !someoneIsRunningTheLight){
    go(); 
}

Suponiendo que esos dos booleanos pueden cambiar en cualquier momento, ¿cómo puedo activar migo() ¿Método cuando cambian según mis condiciones?

Creo que deberías echar un vistazo a estocodeproject.com/Articles/13914/… MilkyWayJoe
Envuélvalos en objetos con los métodos getter y setter, luego active el evento en el setter. Mike Christensen
¿Qué has probado ya? Jamie Keeling

Tu respuesta

7   la respuesta
1

var trafficLightIsGreen = false; 
var someoneIsRunningTheLight = false;

var setTrafficLightIsGreen = function(val){
    trafficLightIsGreen = val;
    if (trafficLightIsGreen and !someoneIsRunningTheLight){
        go(); 
    };
};
var setSomeoneIsRunningTheLight = function(val){
    trafficLightIsGreen = val;
    if (trafficLightIsGreen and !someoneIsRunningTheLight){
        go(); 
    };
};

y luego, en lugar de asignar un valor a una variable, simplemente invoca al definidor:

setTrafficLightIsGreen(true);
0

o usar una función especial para modificar su contenido. o accede a ellos a través dewindow.

El siguiente código se puede usar para desencadenar eventos personalizados cuando los valores se han cambiado siempre que use el formatochangeIndex(myVars, 'variable', 5); en comparación convariable = 5;

Ejemplo:

function changeIndex(obj, prop, value, orgProp) {
    if(typeof prop == 'string') { // Check to see if the prop is a string (first run)
        return changeIndex(obj, prop.split('.'), value, prop);
    } else if (prop.length === 1 && value !== undefined &&
               typeof obj[prop[0]] === typeof value) {
        // Check to see if the value of the passed argument matches the type of the current value
        // Send custom event that the value has changed
        var event = new CustomEvent('valueChanged', {'detail': {
                                                          prop : orgProp,
                                                          oldValue : obj[prop[0]],
                                                          newValue : value
                                                       }
                                                     });
        window.dispatchEvent(event); // Send the custom event to the window
        return obj[prop[0]] = value; // Set the value
    } else if(value === undefined || typeof obj[prop[0]] !== typeof value) {
        return;
    } else {
        // Recurse through the prop to get the correct property to change
        return changeIndex(obj[prop[0]], prop.slice(1), value);
    }
,};
window.addEventListener('valueChanged', function(e) {
    console.log("The value has changed for: " + e.detail.prop);
});
var myVars = {};
myVars.trafficLightIsGreen = false;
myVars.someoneIsRunningTheLight = false;
myVars.driverName = "John";

changeIndex(myVars, 'driverName', "Paul"); // The value has changed for: driverName
changeIndex(myVars, 'trafficLightIsGreen', true); // The value has changed for: traggicIsGreen
changeIndex(myVars, 'trafficLightIsGreen', 'false'); // Error. Doesn't set any value

var carname = "Pontiac";
var carNumber = 4;
changeIndex(window, 'carname', "Honda"); // The value has changed for: carname
changeIndex(window, 'carNumber', 4); // The value has changed for: carNumber

Si siempre quisiste tirar de lawindow objeto que puedes modificarchangeIndex Para establecer siempre obj para ser ventana.

0

setInterval/Timeout.

Si solo puedes soportar Firefox, puedes usarhttps://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/watch

Lo que te dirá cuándo cambia una propiedad de un objeto.

Probablemente, su mejor solución sea hacer que formen parte de un objeto y agregar captadores, configuradores que usted mismo puede enviar notificaciones, como lo mostró JaredPar en su respuesta.

29

pt. Lo que puede hacer es proporcionar un conjunto de funciones que envuelven los valores específicos y generan eventos cuando se les llama para modificar los valores.

function Create(callback) {
  var isGreen = false;
  var isRunning = false;
  return { 
    getIsGreen   : function()  { return isGreen; },
    setIsGreen   : function(p) { isGreen = p; callback(isGreen, isRunning); },
    getIsRunning : function()  { return isRunning; },
    setIsRunning : function(p) { isRunning = p; callback(isGreen, isRunning); }
  };
}

Ahora puede llamar a esta función y vincular la devolución de llamada para ejecutarir():

var traffic = Create(function(isGreen, isRunning) {
  if (isGreen && !isRunning) {
    go();
  }
});

traffic.setIsGreen(true);
+1 acabo de empezar a escribir :) gran respuesta! Ja͢ck
0

undo entre cheques, podría colocar

window.setInterval()

en él, por ejemplo, esto no bloqueará su navegador:

window.setInterval(function() {
    if (trafficLightIsGreen && !someoneIsRunningTheLight) {
        go();
    }
}, 1);
¿Sería esta una buena práctica de codificación, usandosetInterval En lugar de getters y setters? lowtechsun
2
//ex:
/*
var x1 = {currentStatus:undefined};
your need is x1.currentStatus value is change trigger event ?
below the code is use try it.
*/
function statusChange(){
    console.log("x1.currentStatus_value_is_changed"+x1.eventCurrentStatus);
};

var x1 = {
    eventCurrentStatus:undefined,
    get currentStatus(){
        return this.eventCurrentStatus;
    },
    set currentStatus(val){
        this.eventCurrentStatus=val;
    }
};
console.log("eventCurrentStatus = "+ x1.eventCurrentStatus);
x1.currentStatus="create"
console.log("eventCurrentStatus = "+ x1.eventCurrentStatus);
x1.currentStatus="edit"
console.log("eventCurrentStatus = "+ x1.eventCurrentStatus);
console.log("currentStatus = "+ x1.currentStatus);
0
function should_i_go_now() {
    if(trafficLightIsGreen && !someoneIsRunningTheLight) {
        go();
    } else {
        setTimeout(function(){
            should_i_go_now();
        },30);
    }
}
setTimeout(function(){
    should_i_go_now();
},30);

Preguntas relacionadas