2012-04-25 28 views
7

Giả sử tôi có một đối tượng, với một số tài sản và phương pháp:Đối tượng và người nghe sự kiện, thực hành tốt nhất?

var Form = { 
    name: 'sign-up', 

    show: function() {...}, 
    hide: function() {...}, 
    validate: function() {...}, 
    updateCurrency: function() {...}, 
    handleCheckBox: function() {...} 
} 

Bây giờ tôi muốn gọi các phương thức khác nhau khi các sự kiện nhất định xảy ra trong hình thức của tôi như vậy:

$('#country-select').bind('change', function() { 
    Form.updateCurrency(); 
}); 

$("input[type='checkbox']").bind('change', function() { 
    Form.handleCheckBox(); 
}); 

tôi có rất nhiều những người nghe sự kiện này, và thành thật mà nói, tôi thấy họ xấu xí được liệt kê từng người một như thế và không bị ràng buộc trực tiếp với đối tượng mà họ liên quan đến. Có cách nào thanh lịch hơn để gói gọn chúng trong đối tượng theo nghĩa đen của tôi Form không? Có cách nào tốt nhất không?

Trả lời

6

Tôi thích @gillesc câu trả lời, nó đang đi đúng hướng. Tuy nhiên, tôi nghĩ chúng ta có thể làm tốt hơn.

Vấn đề chính với câu trả lời là @gillesc là thiếu khía cạnh động của sự vật (trình xử lý sự kiện chẳng hạn), nó cũng buộc bạn định nghĩa hàm gọi lại xấu xí.

Vì vậy, đó là cách tôi nghĩ bạn nên giải quyết vấn đề của mình.

// Test object 
var testObj = { 
    // Our event handlers. 
    // Notice how we must only define the callback function name here. 
    // Not the function itself. The callback function must be defined in testObj. 
    handlers: { 
     '#form submit': 'onSubmit' 
    }, 
    // Method that will register all handlers to some selector 
    registerHandlers: function() { 
     var that = this; 
     // Go through the handlers list. 
     $.each(this.handlers, function(k, v) { 
      // Parsing the event to two different parts. 
      // 1. trigger event 
      // 2. selector 
      var split = k.split(" "), 
       el = split[0], 
       trigger = split[1]; 

      // Delegating the trigger to selector 
      $(document).delegate(el, trigger, that[v]); 
     }); 
    }, 
    // Our actual callback function 
    onSubmit: function(evt) { 
     evt.preventDefault(); 
     alert("submit"); 
    } 
}; 

Mọi thứ hoạt động như thế nào? Thats dễ dàng! Chúng tôi chỉ cần gọi số testObj.registerHandlers().

JSFiddle demo

+0

Ngoài ra những gì tốt về phương pháp này là bạn không bị buộc phải có phương pháp registerHandlers trong đối tượng của bạn. Đã làm một ví dụ thực sự nhanh chóng/bẩn của những gì tôi có ý nghĩa. [Bản trình diễn JSFiddle tại đây] (http://jsfiddle.net/E3xyz/3/) – Kirstein

3

Tổ chức đánh dấu của bạn tốt hơn và thêm lớp vào phần tử khớp với các phương thức xử lý sự kiện để bạn có thể dễ dàng tạo danh sách trình xử lý và lặp lại chúng để liên kết chúng với các phần tử được nhắm mục tiêu.

Var Form = { 
    ...., 
    handlers: { 
     country: function() {}, 
     checkbox: function() {} 
    } 
}; 

$.each(FORMS.handlers, function(k, v) { 
    $('.' + k).on('change', v); 
}); 


<select class="country">....</select> 
<input class="checkbox" type="checkbox" /> 

Sau đó, tất cả các bạn phải làm là thêm các lớp và xử lý để mở rộng

+0

Điều này là hoàn hảo cho các trình xử lý chung (đính kèm sự kiện qua tên lớp). –

0

Vâng, bạn không cần phải quấn chức năng của mình theo chức năng hơn cho một sự khởi đầu. Bạn không thể chỉ:

$('#country-select').bind('change', Form.updateCurrency); 
$("input[type='checkbox']").bind('change', Form.handleCheckBox); 
+0

Yeaaah .. nhưng bỏ qua những thứ khác mà tôi có thể đang thực hiện trong khi gọi lại như preventDefault(). Nó cũng không giúp tôi đóng gói các trình xử lý sự kiện trong đối tượng như tôi muốn làm .. – alnafie

+0

Trong trường hợp này bạn có thể bọc phương thức bind (và phương thức bind của bạn kết thúc xử lý sự kiện), nếu không (trong ví dụ của bạn trong câu hỏi của bạn)), bạn đang mất tham chiếu đến sự kiện, vậy làm cách nào để 'handleCheckBox' xử lý hộp kiểm của bạn? –

Các vấn đề liên quan