2010-03-19 38 views
5

Tôi đang tìm cách thêm một EventListener sẽ tự động xóa sau lần đầu tiên nó kích hoạt, nhưng tôi không thể tìm ra cách làm theo cách tôi muốn .AS3 - Trình nghe sự kiện chỉ kích hoạt một lần

tôi thấy chức năng này (here):

public class EventUtil 
{ 
    public static function addOnceEventListener(dispatcher:IEventDispatcher,eventType:String,listener:Function):void 
    { 
     var f:Function = function(e:Event):void 
     { 
       dispatcher.removeEventListener(eventType,f); 
       listener(e); 
      } 
      dispatcher.addEventListener(eventType,f); 
    } 
} 


Nhưng thay vì phải viết:

EventUtil.addOnceEventListener(dispatcher, eventType, listener); 

Tôi muốn sử dụng nó theo cách thông thường:

dispatcher.addOnceEventListener(eventType, listener); 


Có ai có ý tưởng về việc làm thế nào để làm điều này ne?
Bất kỳ trợ giúp nào cũng sẽ được đánh giá cao.


(Tôi biết rằng Robert Penner của Signals thể làm điều này, nhưng tôi không thể sử dụng chúng vì nó có nghĩa là rất nhiều mã viết lại rằng tôi không thể đủ khả năng cho dự án hiện tại của tôi)

+0

Hãy thử sử dụng [Tín hiệu Library] (https://github.com/robertpenner/as3-signals/wiki). –

Trả lời

11

tôi tìm cách sạch mà không sử dụng tĩnh hoặc rối tung lên mã của bạn với tiếng ồn là để xác định một chức năng toàn cầu (trong một tập tin gọi là removeListenerWhenFired.as) như sau:

package your.package 
{ 
    import flash.events.Event; 
    import flash.events.IEventDispatcher; 

    public function removeListenerWhenFired(callback:Function, useCapture:Boolean = false):Function 
    { 
     return function (event:Event):void 
     { 
      var eventDispatcher:IEventDispatcher = IEventDispatcher(event.target) 
      eventDispatcher.removeEventListener(event.type, arguments.callee, useCapture) 
      callback(event) 
     } 
    } 
} 

Sau đó, bạn có thể lắng nghe cho các sự kiện như sau:

import your.package.removeListenerWhenFired 

// ... class definition 

    sprite.addEventListener(MouseEvent.CLICKED, 
     removeListenerWhenFired(
      function (event:MouseEvent):void { 
       ... do something 
      } 
     ) 
    ) 
+0

Đó là một mẹo hay mà tôi không nghĩ đến, cảm ơn! –

+0

không có vấn đề;) đóng cửa thực sự rất tiện dụng. Tôi đang xây dựng một túi đầy đủ các đóng cửa và thủ thuật chức năng toàn cầu, nhìn thấy nơi mà tất cả sẽ đi. –

+0

Bạn sẽ xóa thủ công người nghe như vậy theo cách thủ công như thế nào, vì người nghe bạn đang thêm là một chức năng ẩn danh? Nếu bạn không thể loại bỏ nó bằng tay thì sớm hay muộn bạn sẽ bị nhai một lỗi. – chichilatte

2

tôi đã không thử nó, nhưng bạn chỉ có thể biến phương thức tĩnh EventUtil thành một phương thức chuẩn và mở rộng lớp trong đối tượng của bạn.

public class OnceEventDispatcher 
{ 
    public function addOnceEventListener(eventType:String,listener:Function):void 
    { 
     var f:Function = function(e:Event):void 
     { 
       this.removeEventListener(eventType,f); 
       listener(e); 
      } 
      this.addEventListener(eventType,f); 
    } 
} 

public class Example extends OnceEventDispatcher 
{ 


} 

var ex:Example = new Example(); 
ex.addOnceEventListener(type, func); 
+0

Tôi không thể sử dụng thừa kế vì AS3 không cho phép đa kế thừa, và hầu hết các lớp của tôi đã mở rộng một lớp khác. Tôi đã nghĩ đến việc đặt hàm này vào một tệp .as bên ngoài mà tôi sẽ đưa vào trong tất cả các lớp của mình, nhưng tôi đã tự hỏi liệu có cách nào tốt hơn để thực sự làm điều này không. –

+0

Tôi cũng có thể thêm hàm vào lớp UIComponent trực tiếp trong Flex SDK; điều đó sẽ giải quyết vấn đề của tôi, nhưng nó thậm chí còn xấu hơn =/ –

1
functionadd.addEventListener(COMPLETE,functionremove); 

functionremove() 
{ 
    runevent(); 
    functionadd.removeEventListener(COMPLETE,functionremove); 
} 
function runevent() 
{ 
    trace('Hello'); 
} 
Các vấn đề liên quan