2012-05-17 37 views
18

Tôi có hai biến:Trong javascript, cách kích hoạt sự kiện khi giá trị của biến được thay đổi?

var trafficLightIsGreen = false; 
var someoneIsRunningTheLight = false; 

Tôi muốn kích hoạt một sự kiện khi hai biến đồng ý với điều kiện của tôi:

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

Giả sử rằng hai phép toán có thể thay đổi trong bất cứ lúc nào, làm thế nào có thể Tôi kích hoạt phương pháp go() của mình khi chúng thay đổi theo các điều kiện của tôi?

+1

Bạn đã thử cái gì? –

+0

Đưa chúng vào các đối tượng bằng các phương thức getter và setter, sau đó kích hoạt sự kiện trong setter. –

+1

Tôi nghĩ bạn có thể muốn xem qua http://www.codeproject.com/Articles/13914/Observer-Design-Pattern-Using-JavaScript – MilkyWayJoe

Trả lời

27

Không có sự kiện đó được nâng lên khi một giá trị nhất định là đã thay đổi trong Javascript. Những gì bạn có thể làm là cung cấp một tập hợp các hàm bao bọc các giá trị cụ thể và tạo các sự kiện khi chúng được gọi để sửa đổi các giá trị.

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

Bây giờ bạn có thể gọi chức năng này và liên kết các callback để thực hiện go():

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

traffic.setIsGreen(true); 
+0

+1 tôi chỉ mới bắt đầu nhập :) câu trả lời tuyệt vời! –

0

Không có cách nào để thực hiện việc này mà không cần bỏ phiếu với setInterval/Timeout.

Nếu bạn có thể hỗ trợ Firefox chỉ, bạn có thể sử dụng https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/watch

Mà sẽ cho bạn biết khi một tài sản của một đối tượng thay đổi.

giải pháp tốt nhất của bạn có lẽ là làm cho chúng một phần của một đối tượng và thêm thu khí, setters mà bạn có thể gửi thông báo cho mình, như JaredPar cho thấy trong câu trả lời của ông

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

Cách đáng tin cậy nhất là sử dụng setters như thế:

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

và sau đó thay vì chỉ định giá trị cho biến, bạn chỉ cần gọi setter:

setTrafficLightIsGreen(true); 
0

Bạn luôn có thể có các biến là một phần của đối tượng và sau đó sử dụng chức năng đặc biệt để sửa đổi nội dung của đối tượng. hoặc truy cập chúng qua window.

Các mã sau đây có thể được sử dụng để bắn các sự kiện tùy chỉnh khi giá trị đã được thay đổi chừng nào bạn sử dụng định dạng changeIndex(myVars, 'variable', 5); so với variable = 5;

Ví dụ:

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 

Nếu bạn luôn muốn kéo từ đối tượng window bạn có thể sửa đổi changeIndex để luôn đặt obj thành cửa sổ.

0

Nếu bạn đã sẵn sàng để có khoảng một sự chậm trễ 1 mili giây giữa séc, bạn có thể đặt

window.setInterval() 

vào nó, ví dụ này sẽ không sụp đổ trình duyệt của bạn:

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

Đây có phải là thực hành mã hóa tốt, sử dụng 'setInterval' thay vì getters và setters không? – 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); 
Các vấn đề liên quan