Pytanie w sprawie javascript – W javascript, jak wywołać zdarzenie, gdy wartość zmiennej jest zmieniona? [duplikować]

20

To pytanie ma już tutaj odpowiedź:

Słuchanie zmiennych zmian w JavaScript 17 odpowiedzi

Mam dwie zmienne:

var trafficLightIsGreen = false; 
var someoneIsRunningTheLight = false;

Chciałbym wyzwolić zdarzenie, gdy dwie zmienne zgadzają się z moimi warunkami:

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

Zakładając, że te dwa booleany mogą się zmienić w każdej chwili, jak mogę wyzwolić mojego() metoda, gdy zmieniają się zgodnie z moimi warunkami?

Zawijaj je w obiekty metodami getter i setter, a następnie wyzwalaj zdarzenie w ustawniku. Mike Christensen
Myślę, że możesz na to spojrzećcodeproject.com/Articles/13914/… MilkyWayJoe
Co już próbowałeś? Jamie Keeling

Twoja odpowiedź

7   odpowiedzi
29

które jest wywoływane, gdy dana wartość zostanie zmieniona w Javascript. To, co możesz zrobić, to dostarczyć zestaw funkcji, które zawijają określone wartości i generują zdarzenia, gdy są wywoływane 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żesz wywołać tę funkcję i połączyć wywołanie zwrotne, aby wykonaćudać się():

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

traffic.setIsGreen(true);
+1 dopiero zacząłem pisać :) świetna odpowiedź! Ja͢ck
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

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 przypisywania wartości do zmiennej, wywołujesz seter:

setTrafficLightIsGreen(true);
0

a następnie użyć specjalnej funkcji, aby zmodyfikować jego zawartość. lub uzyskaj do nich dostęp przezwindow.

Poniższy kod może być użyty do wystrzelenia niestandardowych zdarzeń, gdy wartości zostały zmienione tak długo, jak używasz formatuchangeIndex(myVars, 'variable', 5); w porównaniu dovariable = 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łeś wyciągnąć zwindow obiekt, który możesz zmodyfikowaćchangeIndex zawsze ustawić obj jako okno.

0

setInterval/Timeout.

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

Co powie Ci, kiedy zmieni się właściwość obiektu.

Twoim najlepszym rozwiązaniem jest prawdopodobnie uczynienie ich częścią obiektu i dodanie getterów, seterów, które możesz wysyłać powiadomienia samodzielnie, jak pokazał JaredPar w swojej odpowiedzi

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

iami, możesz to zrobić

window.setInterval()

na przykład nie spowoduje to awarii przeglądarki:

window.setInterval(function() {
    if (trafficLightIsGreen && !someoneIsRunningTheLight) {
        go();
    }
}, 1);
Czy byłaby to dobra praktyka kodowaniasetInterval zamiast getterów i setterów? lowtechsun

Powiązane pytania