2009-02-06 5 views
71

Tôi đã tạo ra một 'điều khiển' bằng cách sử dụng jQuery và sử dụng jQuery.extend để hỗ trợ làm cho nó thành OO nhất có thể.Kiểm soát giá trị của 'this' trong một sự kiện jQuery

Trong initialisation tầm kiểm soát của tôi, tôi dây lên các sự kiện nhấp chuột khác nhau như vậy

jQuery('#available input', 
      this.controlDiv).bind('click', this, this.availableCategoryClick); 

Chú ý rằng tôi đang Pasing 'này' như là đối số dữ liệu trong phương pháp ràng buộc. Tôi làm điều này để tôi có thể lấy dữ liệu được gắn vào cá thể điều khiển thay vì từ phần tử kích hoạt sự kiện nhấn.

này hoạt động hoàn hảo, tuy nhiên tôi nghi ngờ có một cách tốt hơn

Sau khi sử dụng thử nghiệm trong quá khứ, tôi nhớ một cú pháp ràng buộc cho phép bạn kiểm soát những gì giá trị của 'này' là trong sự kiện này.

Cách jQuery là gì?

+0

Dunno lý do tại sao bạn đang cố gắng làm cho jQuery OO kể từ jQuery hoạt động hiệu quả hơn OO. – cletus

Trả lời

98

Bạn có thể sử dụng jQuery.proxy() với chức năng ẩn danh, chỉ là một chút vụng về đó là bối cảnh 'là tham số thứ hai.

$("#button").click($.proxy(function() { 
    //use original 'this' 
},this)); 
20

Tôi không nghĩ jQuery có tính năng tích hợp cho điều đó. Nhưng bạn có thể sử dụng một helper xây dựng như sau:

Function.prototype.createDelegate = function(scope) { 
    var fn = this; 
    return function() { 
     // Forward to the original function using 'scope' as 'this'. 
     return fn.apply(scope, arguments); 
    } 
} 

// Then: 
$(...).bind(..., obj.method.createDelegate(obj)); 

Bằng cách này, bạn có thể tạo 'chức năng wrapper' năng động với createDelegate() mà gọi phương thức với một đối tượng nhất định như phạm vi 'này' của nó.

Ví dụ:

function foo() { 
    alert(this); 
} 

var myfoo = foo.createDelegate("foobar"); 
myfoo(); // calls foo() with this = "foobar" 
+39

Guys, bài đăng này được viết vào tháng 2 năm 2009, tại thời điểm này chưa có 'jQuery.proxy()' (xuất hiện trong v.1.4, Jan 2010). Không cần phải downvote. –

+5

Không phải là về việc đưa ra câu trả lời hay nhất cho nhiều phiếu bầu nhất? Tôi đánh giá cao nếu các câu trả lời lỗi thời bị bỏ phiếu hoặc bỏ phiếu. Nó giúp tránh IMHO misguidance. – ben

+1

Tất nhiên câu trả lời hay nhất sẽ nhận được nhiều phiếu bầu nhất, vì đây là trường hợp ở đây. Nhưng điều này không có nghĩa là các câu trả lời thứ hai tốt nhất nên được bỏ phiếu. Điều đó làm giảm danh tiếng và đơn giản là không công bằng. Những gì bạn mong đợi tôi để làm gì? Kiểm tra và sửa lại câu trả lời cổ xưa của tôi một cách thường xuyên? –

2

jQuery không hỗ trợ với phím tắt và cách ưa thích là sử dụng chức năng này.

Bởi vì trong Javascript, this.availableCategoryClick không có nghĩa là gọi hàm availableCategoryClick trên đối tượng này, jQuery tư vấn để sử dụng cú pháp ưa thích này:

var self = this; 
jQuery('#available input', self.controlDiv).bind('click', function(event) 
{ 
    self.availableCategoryClick(event); 
}); 

khái niệm OO trong Javascript là khó hiểu, lập trình functionnal thường dễ dàng hơn và dễ đọc hơn.

1

Thấy rằng chức năng thay đổi phạm vi, cách phổ biến nhất là làm điều đó bằng tay, với một cái gì đó như var self = this.

var self = this 

$('.some_selector').each(function(){ 
    // refer to 'self' here 
} 
+0

quy ước nói rằng bạn nên sử dụng 'đó' thay vào đó .. – Orlando

36

Tôi thích theo cách của bạn, trên thực tế sử dụng một cấu trúc tương tự:

$('#available_input').bind('click', {self:this}, this.onClick); 

và dòng đầu tiên của this.onClick:

var self = event.data.self; 

Tôi thích cách này bởi vì sau đó bạn sẽ có được cả phần tử được nhấp (như thế này) và đối tượng "này" là tự mà không phải sử dụng các bao đóng.

+0

điều này thực tế rất hữu ích, cách tiếp cận tốt nhất mà tôi đã nhìn thấy cho đến nay .. cảm ơn dude! –

+0

Giải pháp gọn gàng. Tôi thích nó. –

+0

Ý tưởng tuyệt vời, cảm ơn! –

32

jQuery có phương thức jQuery.proxy (có sẵn từ 1.4).

Ví dụ:

var Foo = { 
    name: "foo", 

    test: function() { 
    alert(this.name) 
    } 
} 

$("#test").click($.proxy(Foo.test, Foo)) 
// "foo" alerted 
4

bạn có thể sử dụng phương pháp javascript bind như thế này:

var coolFunction = function(){ 
    // here whatever involving this 
    alert(this.coolValue); 
} 

var object = {coolValue: "bla"}; 


$("#bla").bind('click', coolFunction.bind(object)); 
+0

Alas này dường như chỉ trong JS 1.8.5, và điều này cắt ra các trình duyệt như IE8. –

+1

@LukeH ràng buộc phương pháp chỉ là một số mã js .. https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/bind – Orlando

+1

@JLRishe bạn có thể sử dụng [polyfill] này (https: //developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind#Compatibility) cho IE8 – Orlando

4

HTML trình duyệt 5-compliant cung cấp một bind method trên Function.prototype đó là, có lẽ là cú pháp sạch và không phải là khuôn khổ phụ thuộc, mặc dù nó không được tích hợp vào IE cho đến IE 9. (Tuy nhiên, có polyfill đối với các trình duyệt không có nó.)

Dựa trên ví dụ của bạn, bạn có thể sử dụng nó như sau:

jQuery('#available input', 
     this.controlDiv).bind('click', this.availableCategoryClick.bind(this)); 

(phụ lưu ý: bind đầu tiên trong bản Tuyên Bố này là một phần của jQuery và không có gì để làm với Function.prototype.bind)

Hoặc sử dụng hơi ngắn gọn hơn và to-date up-jQuery (và tránh nhầm lẫn từ hai loại khác nhau của bind s):

$('#available input', this.controlDiv).click(this.availableCategoryClick.bind(this));