كيفية إنشاء مخصص الحدث MouseEvent.CLICK في AS3 (معلمات تمريرة من العمل)؟

StackOverflow https://stackoverflow.com/questions/426540

سؤال

وهذا السؤال لا يتعلق فقط MouseEvent.CLICK نوع الحدث ولكن لجميع أنواع الأحداث الموجودة بالفعل في AS3. قرأت الكثير عن أحداث مخصصة ولكن حتى الآن لم أتمكن من معرفة ذلك كيف أن تفعل ما أريد القيام به. انا ذاهب الى محاولة لتفسير، وآمل أن يفهم:

وهنا هو التوضيح من وضعي:

for(var i:Number; i < 10; i++){
    var someVar = i;
     myClips[i].addEventListener(MouseEvent.CLICK, doSomething);
}

function doSomething(e:MouseEvent){ /* */ }

ولكن أريد أن أكون قادرة على تمرير <م> someVar كمعلمة إلى <م> تنفيذ DoSomething . لذلك حاولت هذه:

for(var i:Number; i < 10; i++){

    var someVar = i;
    myClips[i].addEventListener(MouseEvent.CLICK, function(){
        doSomething(someVar);
    });
}

function doSomething(index){ trace(index); }

وهذا النوع من الأعمال ولكن ليس كما أتوقع. بسبب الإغلاق المستمر للمعابر وظيفة، عندما أطلق الأحداث MouseEvent.CLICK الواقع <م> ل حلقة بالفعل مرارا و<م> someVar تحتجز القيمة الأخيرة، وعدد <م> 9 في المثال. لذلك كل نقرة في كل مقطع الفيلم سيدعو <م> تنفيذ DoSomething يمر <م> 9 كمعلمة. وانها ليست ما أريد.

واعتقدت أن خلق حدث مخصص يجب أن تعمل، ولكن بعد ذلك لم استطع العثور على وسيلة لإطلاق حدث مخصص عندما يتم تشغيل الحدث MouseEvent.CLICK وتمرير المعلمة إليها. الآن أنا لا أعرف إذا كان هذا هو الجواب الصحيح.

وماذا علي أن أفعل وكيف؟

هل كانت مفيدة؟

المحلول

ودون أن يعرفوا المزيد عن التطبيق الخاص بك، يبدو أشبه يجب عليك استخدام الهدف لتمرير معلمات أو تمديد MouseEvent. سوف السابق تكون أكثر انسجاما مع ممارسة شائعة، وإن كان. هكذا على سبيل المثال، إذا كنت تتعرض لممتلكات عامة صحيح على هاتفك الكائن "كليب" (أيا كانت):

public class MyClip
{
   public var myPublicProperty:int;

   public function MyClip() { //... }
}

for (var i:int = 0; i < 10; i++)
{
   myClips[i].myPublicProperty = i;
   myClips[i].addEventListener(MouseEvent.CLICK, doSomething);
}

... ثم في المستمع هذا الحدث الخاص بك، هل يمكن استرداد تلك الخاصية باستخدام إما الهدف أو الممتلكات currentTarget الحدث (ربما currentTarget، في قضيتك):

function doSomething(event:MouseEvent):void
{
   trace(event.currentTarget.myPublicProperty.toString());
}

وهذا يجب أن تفعل ذلك! حظا سعيدا.

نصائح أخرى

وكنت حقا بحاجة لتوسيع فئة الحدث لخلق الحدث الخاص بك مع معلمات إضافية. وضع وظائف داخل addEventListener (وظائف مجهول) هو وصفة للتسرب الذاكرة، وهي ليست جيدة. نلقي نظرة على ما يلي.

import flash.events.Event;

//custom event class to enable the passing of strings along with the actual event
public class TestEvent extends Event
{
    public static const TYPE1 :String = "type1";
    public static const TYPE2 :String = "type2";
    public static const TYPE3 :String = "type3";

    public var parameterText:String;

    public function TestEvent (type:String, searchText:String)
    {
        this.parameterText = searchText;
        super(type);
    }

}

وعند إنشاء حدث جديد مثل

dispatchEvent(new TestEvent(TestEvent.TYPE1, 'thisIsTheParameterText'))" ;

وبعد ذلك يمكنك الاستماع لهذا الحدث مثل هذا

someComponent.addEventListener(TestEvent.TYPE1, listenerFunction, true , 0, true);

والداخل وظيفة سوف "listenerFunction" event.parameterText يحتوي على المعلمة الخاص بك.

وحتى داخل المكون myClips بك كنت اطلاق النار قبالة حدث مخصص والاستماع لهذا الحدث، وليس الحدث.

    private function myCallbackFunction(e:Event, parameter:String):void
    {
         //voila, here's your parameter
    }

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

    var parameter:String = "A sentence I want to pass along";
    movieClip.addEventListener(Event.COMPLETE, addArguments(myCallbackFunction, [parameter] ) );

والاستفادة من بناء وظيفة حيوية في AS3.

ويمكنك تحقيق ذلك عن طريق الحصول على معالج للخروج من وظيفة التي تعطي إغلاق متغير، مثل هذا:

for (var i=0; i<5; i++) {
    myClips[i].addEventListener( MouseEvent.CLICK, getHandler(i) );
}

function getHandler(i) {
    return function( e:MouseEvent ) {
        test(i);
    }
}

function test( j ) {
    trace("foo "+j);
}

وأيضا، أما بالنسبة لماذا هذا يخلق إغلاق الجديد، فإنك قد ترغب في التحقق من التفسير في الإجابة مقبولة إلى <لأ href = "https://stackoverflow.com/questions/422784/how-to-fix-closure -problem-في أكشن-3-AS3 "> هذا السؤال مماثلة .

وشكرا جزيلا لهذا مفيدة نصائح، وهذا الأسلوب هو أفضل لفهم من تفسير الطبقات.

وبالنسبة لي أنا فقط التي خوارزمية برمجية جديدة باستخدام هذه التقنية لحل علاقة الارتباط بين توقيت مجموعة ومنافذ العرض مجموعة، وحالة التحديث التي نص التغيير داخلها كثير من الأحيان، عن طريق تمرير معرف مع الأحداث توقيت.

ومثل هذا:

    var view:Object=[];

    for(var i:uint=0;i<Camera.names.length;i++){

    view[i]=getChildByName("Cam"+i);

    //_________ Add Text _________
    var tf:TextField = new TextField();
    tf.autoSize = TextFieldAutoSize.LEFT;
    tf.textColor=0xffffff;
    view[i].tf=view[i].addChild(tf);

    //_________ Add Timer _________
    var t:Timer = new Timer(1000);
    view[i].timer=t;
    view[i].timer.start();
    view[i].timer.addEventListener(TimerEvent.TIMER, addArg(i)); 
}

function addArg(adi:uint):Function {
    return function(event:TimerEvent):void {
        updatecamstatus(adi);
    }
}
function updatecamstatus(vH:uint):void {
   with (view[vH]){
    tf.text="Cam" + vH + "\n";
    tf.appendText("activityLevel: " + videosource.activityLevel + "\n"); 
    tf.appendText("motionLevel: " + videosource.motionLevel + "\n"); 
   }
}

وأرى الهدف الرئيسي الخاص بك ليست في الواقع لخلق العرف MouseEvent.CLICK، ولكن لتمرير معلمة إلى الدالة. أنت لا تحتاج إلى complicatedly إنشاء أو توسيع أي شيء. هناك طريقة بسيطة وخالية من المتاعب إغلاق للقيام بذلك.

وجعل مجرد وظيفة الخاصة بك مثل هذا:

function doSomething(index:Number):Function {
  return function(e:MouseEvent):void {
    // Use "e" and "index" here. They'll be unique for each addEventListener()
    trace(index);
  }
}

وهذه التقنية يمكن أن تتصل بأي AS3 نوع الحدث يمكنك استخدام addEventListener جرا.

والآن يمكنك إضافته مثل هذا:

var functionsDoSomething:Object;

for (var i:Number = 0; i < 10; i++) {
  var someVar:Number = i;
  functionsDoSomething[i] = doSomething(someVar);
  myClips[i].addEventListener(MouseEvent.CLICK, functionsDoSomething[i]);
}

ووdoSomething(someVar) يمكن استخدامها مباشرة على addEventListener()، ولكن من الأفضل أن يبقيه في متغير لأنك سوف تكون قادرة على إزالته في وقت لاحق بنفس الطريقة قمت بإضافة ما يلي:

for (i = 0; i < 10; i++) {
  myClips[i].removeEventListener(MouseEvent.CLICK, functionsDoSomething[i]);
}

ووe.currentTarget.someCustomProperty تستخدم عادة يعمل لالكائنات الحيوية (أي مقطع فيلم)، ولكن سوف نخذلكم في أي شيء آخر (أي العفريت)، يجبرك على بناء العرف كله بمد الكائن / حالة لكل نوع.

وهذا الحل يتعامل مع كل كائن "listenable" والحدث. و هذه الإجابة ديه مزيد من التفاصيل والأمثلة على ذلك.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top