2012-05-17 6 views
18

Ho due variabili:In javascript, come attivare l'evento quando viene modificato il valore di una variabile?

var trafficLightIsGreen = false; 
var someoneIsRunningTheLight = false; 

Vorrei attivare un evento quando le due variabili sono d'accordo con le mie condizioni:

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

Supponendo che questi due booleani possono cambiare in qualsiasi momento, come può Attivo il mio metodo go() quando cambiano in base alle mie condizioni?

+1

Cosa hai già provato? –

+0

Avvolgili in oggetti con metodi getter e setter, quindi attiva l'evento nel setter. –

+1

Penso che potresti dare un'occhiata a questo http://www.codeproject.com/Articles/13914/Observer-Design-Pattern-Using-JavaScript – MilkyWayJoe

risposta

27

Non c'è evento che viene generato quando un dato valore è cambiato in Javascript. Quello che puoi fare è fornire un insieme di funzioni che racchiudono i valori specifici e generano eventi quando vengono chiamati per modificare i valori.

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

Ora si può chiamare questa funzione e collegare il callback da eseguire go():

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

traffic.setIsGreen(true); 
+0

+1 ho appena iniziato a digitare :) ottima risposta! –

0

Non c'è modo di farlo senza polling con setInterval/Timeout.

Se si può sostenere solo Firefox, è possibile utilizzare https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/watch

Quale vi dirà quando una proprietà di un oggetto cambia.

La soluzione migliore è probabilmente rendendoli parte di un oggetto e l'aggiunta di getter, setter che è possibile inviare notifiche da soli, come JaredPar ha mostrato nella sua risposta

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

Il modo più affidabile è quello di utilizzare setter così:

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(); 
    }; 
}; 

e quindi anziché assegnare un valore a una variabile, è sufficiente richiamare il setter:

0

Le variabili possono sempre essere parte di un oggetto e quindi utilizzare una funzione speciale per modificarne il contenuto. o accedervi tramite window.

Il seguente codice può essere utilizzato per generare gli eventi personalizzati quando i valori sono stati modificati fino a quando si utilizza il formato changeIndex(myVars, 'variable', 5); rispetto a variable = 5;

Esempio:

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 

Se avete sempre sognato di tirare dall'oggetto window è possibile modificare changeIndex per impostare sempre obj come finestra.

0

se erano disposti ad avere un ritardo di 1 millisecondo tra i controlli, è possibile inserire

window.setInterval() 

su di esso, ad esempio, questo non vada in crash il browser:

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

Sarebbe una buona pratica di codifica, usando 'setInterval' invece di getter e setter? – 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); 
Problemi correlati