2012-05-17 11 views
18

Mam dwie zmienne:W języku javascript, jak wywołać zdarzenie po zmianie wartości zmiennej?

var trafficLightIsGreen = false; 
var someoneIsRunningTheLight = false; 

chciałbym wywołać zdarzenie, kiedy dwie zmienne zgadzają się z moimi warunkami:

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

Zakładając, że te dwie wartości logiczne może się zmienić w każdej chwili, w jaki sposób Wywołuję moją metodę go(), kiedy zmieniają się one zgodnie z moimi warunkami?

+1

Czego już próbowałeś? –

+0

Zawiń je w obiekty metodami gettera i setera, a następnie uruchom zdarzenie w setera. –

+1

Myślę, że możesz chcieć rzucić okiem na ten http://www.codeproject.com/Articles/13914/Observer-Design-Pattern-Using-JavaScript – MilkyWayJoe

Odpowiedz

27

Nie ma zdarzeń, które są wywoływane, gdy dana wartość jest zmieniono w JavaScript. To, co możesz zrobić, to dostarczyć zestaw funkcji, które zawijają określone wartości i generują zdarzenia, gdy zostaną wywołane w celu zmodyfikowania wartości.

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

Teraz można wywołać tę funkcję i powiązać zwrotnego wykonać go():

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

traffic.setIsGreen(true); 
+0

+1 i dopiero co zacząłem pisać :) świetna odpowiedź! –

0

Nie można tego zrobić bez odpytywania z setInterval/Timeout.

Jeśli można obsługiwać tylko Firefoksa, można użyć https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/watch

Co powie, kiedy to właściwość obiektu zmienia.

Najlepszym rozwiązaniem jest prawdopodobnie czyniąc je częścią obiektu i dodanie pobierające, ustawiaczy, że można Informacji na temat opadów siebie, jako JaredPar pokazał w swojej odpowiedzi

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

Najpewniejszym sposobem jest użycie ustawiające tak:

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

, a następnie zamiast przypisać wartość do zmiennej, wystarczy wywołać setter:

setTrafficLightIsGreen(true); 
0

Zawsze można mieć zmienne będące częścią obiektu, a następnie użyć specjalnej funkcji do modyfikacji zawartości tego obiektu. lub uzyskać do nich dostęp poprzez window.

Poniższy kod może być użyty do ognia zdarzeń niestandardowych, gdy wartości zostały zmienione tak długo, jak korzystać z formatu changeIndex(myVars, 'variable', 5); w porównaniu do variable = 5;

Przykład:

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 

Jeśli zawsze chciał ciągnąć z obiektu window można zmodyfikować changeIndex, aby zawsze ustawić obiekt na okno.

0

Jeśli chcieli mieć o opóźnieniu 1 milisekundy pomiędzy kontrolami, można umieścić

window.setInterval() 

na nim, na przykład ten nie padnie przeglądarkę:

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

Czy to byłoby dobre praktyki kodowania, używając 'setInterval' zamiast getters i 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); 
Powiązane problemy