2012-05-17 15 views
18

Tengo dos variables:En javascript, ¿cómo desencadenar el evento cuando se cambia el valor de una variable?

var trafficLightIsGreen = false; 
var someoneIsRunningTheLight = false; 

me gustaría disparar un evento cuando las dos variables están de acuerdo con mis condiciones:

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

Suponiendo que esos dos valores booleanos pueden cambiar en cualquier momento, ¿cómo puede ¿Activo mi método go() cuando cambian de acuerdo con mis condiciones?

+1

¿Qué has probado ya? –

+0

Envuélvalos en objetos con métodos getter y setter, luego active el evento en el setter. –

+1

Creo que es posible que desee echar un vistazo a este http://www.codeproject.com/Articles/13914/Observer-Design-Pattern-Using-JavaScript – MilkyWayJoe

Respuesta

27

No hay evento que se genera cuando un valor dado es cambiado en Javascript. Lo que puede hacer es proporcionar un conjunto de funciones que envuelven los valores específicos y generan eventos cuando son llamados 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 se puede llamar a esta función y vincular la devolución de llamada para ejecutar Go():

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

traffic.setIsGreen(true); 
+0

+1 que acabo de comenzar a escribir :) ¡excelente respuesta! –

0

No hay forma de hacerlo sin sondear con setInterval/Timeout.

Si usted puede apoyar sólo para Firefox, puede utilizar https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/watch

que le dirá cuando una propiedad de un objeto cambia.

La mejor solución es, probablemente, haciéndolos parte de un objeto y la adición de captadores, los emisores que se puede enviar fuera de se notificaciones, como JaredPar mostró en su respuesta

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); 
1

La forma más fiable es el uso de fijadores así:

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, solo invocará al colocador:

setTrafficLightIsGreen(true); 
0

Siempre puede tener las variables ser parte de un objeto y luego usar una función especial para modificar su contenido. o acceda a ellos a través del window.

El código siguiente se puede utilizar para desencadenar eventos personalizados cuando los valores se han cambiado, siempre y cuando se utiliza el formato de changeIndex(myVars, 'variable', 5); en comparación con variable = 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 usted siempre quiso tirar desde el objeto window puede modificar changeIndex para establecer siempre que obj sea una ventana.

0

si estaban dispuestos a tener un retraso de 1 milisegundo entre las comprobaciones, se puede colocar

window.setInterval() 

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

window.setInterval(function() { 
    if (trafficLightIsGreen && !someoneIsRunningTheLight) { 
     go(); 
    } 
}, 1); 
+1

¿Sería esta una buena práctica de codificación, usando 'setInterval' en lugar de getters y setters? – lowtechsun

1
//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); 
Cuestiones relacionadas