2011-06-20 42 views
24

Vì khi sử dụng sql lite nếu bạn thử và thực hiện chức năng tại cùng một thời điểm, nó sẽ cố gắng tạo ra một hàm sẽ kiểm tra xem nó có thực thi hay không và nếu nó thử lại sau 10 mili giây, hàm chính xác này hoạt động tốt nếu tôi không phải vượt qua bất kỳ đối số cho chức năng nhưng im nhầm lẫn làm thế nào tôi có thể vượt qua các vars trở lại vào chức năng nó sẽ được thực hiện.Làm cách nào để truyền đối số vào hàm lắng nghe sự kiện trong flex/actionscript?

tôi muốn làm:

timer.addEventListener(TimerEvent.TIMER, saveChat(username, chatBoxText)); 

Nhưng nó sẽ chỉ cho phép tôi làm:

timer.addEventListener(TimerEvent.TIMER, saveChat); 

Nó mang lại cho tôi lỗi biên dịch này:

1067: Implicit coercion of a value of type void to an unrelated type Function

Làm thế nào tôi có thể nhận được điều này để vượt qua giới hạn này?

Đây là những gì tôi đã có:

public function saveChat(username:String, chatBoxText:String, e:TimerEvent=null):void 
{ 
    var timer:Timer = new Timer(10, 1); 
    timer.addEventListener(TimerEvent.TIMER, saveChat); 

    if(!saveChatSql.executing) 
    { 
     saveChatSql.text = "UPDATE active_chats SET convo = '"+chatBoxText+"' WHERE username = '"+username+"';"; 
     saveChatSql.execute(); 
    } 
    else timer.start(); 
} 

Trả lời

26

Một chức năng gọi bằng một người nghe chỉ có thể có một đối số, đó là sự kiện kích hoạt nó.

listener:Function — The listener function that processes the event. This function must accept an Event object as its only parameter and must return nothing, as this example shows:

function(evt:Event):void

Source

Bạn có thể khắc phục điều này bằng cách có chức năng gọi bằng sự kiện gọi hàm khác với các đối số cần thiết:

timer.addEventListener(TimerEvent.TIMER, _saveChat); 
function _saveChat(e:TimerEvent):void 
{ 
    saveChat(arg, arg, arg); 
} 

function saveChat(arg1:type, arg2:type, arg3:type):void 
{ 
    // Your logic. 
} 

Một điều bạn có thể làm tạo ra một lớp sự kiện tùy chỉnh kéo dài flash.events.Event và tạo các thuộc tính mà bạn cần bên trong.

package 
{ 
    import flash.events.Event; 

    public class CustomEvent extends Event 
    { 
     // Your custom event 'types'. 
     public static const SAVE_CHAT:String = "saveChat"; 

     // Your custom properties. 
     public var username:String; 
     public var chatBoxText:String; 

     // Constructor. 
     public function CustomEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false):void 
     { 
      super(type, bubbles, cancelable); 
     } 
    } 
} 

Sau đó, bạn có thể gửi này có đặc tính được định nghĩa:

timer.addEventListener(TimerEvent.TIMER, _saveChat); 
function _saveChat(e:TimerEvent):void 
{ 
    var evt:CustomEvent = new CustomEvent(CustomEvent.SAVE_CHAT); 

    evt.username = "Marty"; 
    evt.chatBoxText = "Custom events are easy."; 

    dispatchEvent(evt); 
} 

Và nghe cho nó:

addEventListener(CustomEvent.SAVE_CHAT, saveChat); 
function saveChat(e:CustomEvent):void 
{ 
    trace(e.username + ": " + e.chatBoxText); 
    // Output: Marty: Custom events are easy. 
} 
1

Bạn có thể thử này:

var timerHandler:Function = function (event:TimerEvent):void 
{ 
    saveChat(username,chatBoxText,event); 
} 

timer.addEventListener(TimerEvent.TIMER, timerHandler); 
12

Trên thực tế, bạn thể qua tham số bổ sung để một người biết lắng nghe sự kiện mà không cần tạo sự kiện tùy chỉnh bằng cách sử dụng tính năng xây dựng hàm động của Actionscript.

private function addArguments(method:Function, additionalArguments:Array):Function 
{ 
    return function(event:Event):void {method.apply(null, [event].concat(additionalArguments));} 
} 

Khi thiết lập các closeHandler cho cửa sổ cảnh báo chúng ta gọi là addArguments() phương pháp và thông qua trong một mảng continaing tất cả các thông số chúng ta muốn vượt qua các closeHandler. Phương thức addHandler() sẽ trả về hàm chúng ta sẽ gọi khi cửa sổ Alert đóng với các tham số được bao gồm.

protected function btnOK_clickHandler(event:MouseEvent):void 
{ 
    Alert.show("Would you like to reverse the text you just entered?", "", Alert.YES | Alert.NO, null, addArguments(alertCloseHandler, [txtInput.text]), null, Alert.YES); 
    txtInput.text = ""; 
} 
+0

Liên kết không hoạt động – Kukeltje

1

Trên gọi saveChat (arg, arg, arg) nó không phải cho tôi, tôi cần phải vượt qua đối số mà tôi không có trong phương pháp này nhưng tôi có một giải pháp khác

Im luôn sử dụng passParameters phương pháp bổ sung để thêm lập luận mới:

public function passParameters(method:Function,additionalArguments:Array):Function 
{return function(event:Event):void{ 
    method.apply(null, [event].concat(additionalArguments));} 
} 

lời giải thích của việc này là ở đây - nó đơn giản và luôn luôn làm việc http://sinfinity.pl/blog/2012/03/28/adding-parameters-to-event-listener-in-flex-air-as3/

11

1067: Implicit coercion of a value of type void to an unrelated type Function

Chú ý đến lỗi bạn nhận được: nó cho biết rằng Function là loại và addEventListener() muốn loại đó. Mặc dù người nghe của bạn trả về khoảng trống, nó là Function! Vì vậy, điều gì về việc trả lại người nghe?

timer.addEventListener(TimerEvent.TIMER, saveChat(username, chatBoxText)); 
function saveChat(username:String, chatBoxText:String):Function { 
    return function(e:TimerEvent):void { 
    // Do everything that uses "e", "chatBoxText" and "username" here! 
    }; 
} 

đơn giản như thế này. Nó hoạt động cho bất kỳ loại sự kiện nào. Và không có vấn đề đóng cửa.

Lưu ý về removeEventListener():

Đừng cố gắng làm timer.removeEventListener(TimerEvent.TIMER, saveChat(username, chatBoxText)). Nó sẽ không nhận ra hàm của bạn bởi vì bạn sẽ chuyển một hàm mới vào nó mỗi khi bạn sử dụng saveChat(). Thay vào đó, chỉ cần tham chiếu vào biến số và bạn đã hoàn thành:

var functionSaveChat:Function = saveChat(username, chatBoxText); 
timer.addEventListener(TimerEvent.TIMER, functionSaveChat); 
//trace(timer.hasEventListener(TimerEvent.TIMER)); 
timer.removeEventListener(TimerEvent.TIMER, functionSaveChat); 
//trace(timer.hasEventListener(TimerEvent.TIMER)); 
+0

Ồ, điều này thực sự hữu ích. Cảm ơn! Tôi chưa bao giờ thấy khả năng này nhận xét. Có bất kỳ nhược điểm để sử dụng này? Có lẽ có một số rò rỉ bộ nhớ hoặc một cái gì đó như thế? – OMA

+0

@OMA Tôi đã ổn trong nhiều năm với điều này. Nếu bạn muốn chắc chắn, hãy thử nó với một [bộ nhớ profiler] (http://stackoverflow.com/questions/1872687/actionscript-3-profiler-memory-analysis-tool). –

+0

Tuyệt vời, cảm ơn bạn. Trong trường hợp của tôi, instaed của việc lưu tham chiếu đến hàm trong một biến, như bạn đã đề xuất, tôi đang sử dụng event.currentTarget.removeEventListener (MyListener, arguments ['callee']); để xóa người nghe khỏi bên trong hàm. – OMA

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