2009-11-26 3 views
7

Tôi có đối tượng flash của bên thứ ba mà tôi có thể thao tác thông qua API javascript mà họ cung cấp. Tôi đang tryind để nghe một sự kiện trên đối tượng này và sau đó kích hoạt sự kiện bên trong đối tượng của tôi để tăng thêm sự kiện. Tôi tình cờ sử dụng EXT Js nhưng tôi không nghĩ nó quan trọng ở đây.addEventListener và phạm vi của

Mẫu mã

this.chart.addEventListener('create', function() { 
    this.fireEvent('created'); 
}, false) 

Vấn đề của tôi là 'này' bên trong hàm ẩn danh dùng để chỉ đối tượng mà bắn sự kiện này chứ không phải là đối tượng của tôi mà tôi muốn bắn một sự kiện trên.

Vấn đề khác về phạm vi của nó. Cảm ơn trước sự giúp đỡ nào.

Trả lời

0

Đây là phương pháp điển hình cho vấn đề này: -

(function(self) { 
    self.chart.addEventListener('create', function() {self.fireEvent('created');}, false); 
})(this); 
+2

Tôi thích 'var self = this;'. Tạo một hàm và sau đó thực thi nó trong khi truyền 'this' như tham số có vẻ hơi quá mức - mã hơi dài hơn nữa ;-) –

+0

@Andy: Vâng, tôi cũng thường làm điều đó khi mã tồn tại trong ngữ cảnh thực thi nhỏ. Tuy nhiên, ở trên là cách tiếp cận tiêu chuẩn hoạt động trong nhiều kịch bản khác nhau.Phạm vi của định danh 'self' chỉ giới hạn trong việc đóng, không có nguy hiểm là mã tiếp theo có thể sửa đổi giá trị chứa trong nó trước khi sự kiện cháy. Điều này không đúng với phương thức 'var self = this;'. – AnthonyWJones

12

Điều gì về việc tạo biến bên ngoài trước khi tham chiếu đến đối tượng 'this'. Ví dụ:

var _this = this; 
this.chart.addEventListener('create', function() { _this.fireEvent('created'); }, false) 
+4

Vâng, đây là thành ngữ bình thường. Biến đóng cửa thường được gọi là 'that' hoặc' self' (mặc dù tôi không nghĩ ý tưởng tuyệt vời của nó là 'self' có một ý nghĩa đã tồn tại - mặc dù vô nghĩa - hiện có trong JavaScript). – bobince

+0

OK hoạt động. Không quan tâm là có một cách khác hơn là thiết lập một biến cho điều này. Ví dụ bằng cách sử dụng đóng cửa? – Jonnio

+1

@bobince: Tôi thích 'self' hơn. 'self' được hiển thị bởi' window' một tham chiếu đến chính nó. Tôi khá vui khi sử dụng lại số nhận dạng trong các phạm vi khác. Dường như với tôi để mang ý nghĩa đúng đắn và không đụng độ với điều đó, điều đó có nghĩa là khi 'self' cũng là cửa sổ. – AnthonyWJones

5

Trong khi câu trả lời khác thực hiện những gì bạn cần, họ không làm việc trong (khả năng mở rộng) cách hiệu quả nhất , bởi vì cuối cùng họ không tách rời đối tượng xem (this.chart) khỏi logic của chế độ xem đó (fireEvent()). Trong các ứng dụng MVC, các "quyết định" xem này nằm trong bộ điều khiển . Bộ điều khiển "điều khiển" lượt xem và phải chứa tất cả các API mà chế độ xem có thể truy cập.

Trong ví dụ của bạn, this là bộ điều khiển và điều đó tốt (điều đó có nghĩa là bạn đang thêm người nghe vào đúng nơi). Tất cả các bạn thực sự cần phải làm là gắn kết xử lý với phạm vi điều rằng nên làm như "xử lý" - trong trường hợp của bạn: this:

// `this` is the controller of `chart` 
this.chart.addEventListener('create', function() { 
    this.fireEvent('created'); 
}.bind(this)); 

gì câu trả lời khác trên trang này đã làm là làm cho nó để chế độ xem của bạn trở thành bộ điều khiển riêng, nhưng chỉ khi xử lý các sự kiện 'tạo', bằng cách gán một tham chiếu tạm thời cho "bộ điều khiển" sử dụng var self = this. Một lần nữa, điều này hoạt động tốt, nhưng nó không hoạt động tốt ở quy mô trong các ứng dụng hướng sự kiện, và nó không thực sự có ý nghĩa nếu bạn có rất nhiều sự kiện để xử lý.

.bind() là triển khai ECMAScript 5. Nếu cần thiết để làm việc trong các trình duyệt cũ hơn, một phương pháp tốt để làm như vậy được mô tả ở đây (sử dụng functions.call()): https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/bind

+0

Trong một số triển khai MVC (như trong ví dụ được mô tả ở đây: http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller), trình xử lý (ví dụ: '.fireEvent () ') được định nghĩa trong khung nhìn, nhưng bộ điều khiển gọi nó khi cần thiết. Điều này có thể cho phép bạn không sử dụng '.bind()' hoặc một tham chiếu tự ở tất cả, nhưng sẽ làm cho handler của bạn rất unmodular; và ứng dụng của bạn sẽ phát triển rất lớn. – Benny