Как да направя справка по подразбиране `this` в Actionscript3 от външен пакет?

Моят код е външен .as файл. Google предоставя този код в своята демонстрация, която съдържа this ключова дума:

import com.google.analytics.AnalyticsTracker; 
import com.google.analytics.GATracker; 
var tracker:AnalyticsTracker = new GATracker( this, "UA-111-222", "AS3", true ); 
playGame.addEventListener( MouseEvent.CLICK, onButtonClick ); 
function onButtonClick ( event:Event ):void 
{
   tracker.trackPageview("/myGame1"); 
}

Този код вероятно работи добре в контекста по подразбиране, но тъй като вграждам този код във външен .as файл, където дефинирам пакет, очевидно препратката this се различава, тъй като контекстът на изпълнение е различен.

В момента го имам така:

package {
        import flash.display.MovieClip;
        import flash.display.Sprite;
        import flash.events.Event;
        import flash.events.MouseEvent;
        import flash.net.URLRequest;
        import flash.net.navigateToURL;
        import flash.text.TextFieldAutoSize;
        import flash.text.TextFormat;
        import flash.external.ExternalInterface;    

        import com.google.analytics.AnalyticsTracker; 
        import com.google.analytics.GATracker; 

        public class DetailView extends MovieClip {

                //private var tracker:GATracker;
                private var tracker:AnalyticsTracker;

                function slugify(text) {
                        text = text.replace(/[^-a-zA-Z0-9,&\s]+/ig, '');
                        text = text.replace(/-/gi, "_");
                        text = text.replace(/\s/gi, "-");
                        return text.toLowerCase();
                }   

                public static var NEXTOFFER:String = "DETAIL_NEXTOFFER";
                public static var TERMS:String = "DETAIL_TERMS";
                private var link:String;
                private var fbshare:String;
                private var twshare:String;
                private var offerID:Number;
                private var details:Sprite;
                private var terms:Sprite;

                public function DetailView() {
                        ExternalInterface.call( "console.log", 'before');
                        ExternalInterface.call( "console.log", typeof GATracker );
                        ExternalInterface.call( "console.log", typeof this );
                        tracker = new GATracker( this, "UA-WATEVER", "AS3", true );  
                        ExternalInterface.call( "console.log", 'after');

Забележете, че имам 4 обаждания до console.log. Първите 3 се задействат, но след оператора new GATracker, 4-ият не се задейства.

Имам чувството, че замествам целия пакет с обекта, създаден от new GATracker, когато трябва да предавам различен контекст.

Вярвам, че правилният контекст, който трябва да предам, е какъвто и да е this по подразбиране, когато не е вътре в пакет/външен файл, предполагам, че препраща към обекта на главния етап.

Ако предположението ми е правилно, как бих реферирал обекта на главния етап от вътрешността на конструктора?


person meder omuraliev    schedule 07.07.2011    source източник
comment
Получавате ли грешки по време на изпълнение?   -  person JeremyFromEarth    schedule 07.07.2011
comment
Не получавам грешки на компилатора, swf записва добре.   -  person meder omuraliev    schedule 07.07.2011
comment
Само едно предложение, с представителство от 42,1k, изглежда, че сте знаещ кодер. Бих препоръчал да не използвате Flash IDE и да се запознаете с редактор като FlashDevelop (с отворен код, но само за Windows), FlashBuilder или подобен. IDE не е добра за писане и отстраняване на грешки в код.   -  person JeremyFromEarth    schedule 07.07.2011


Отговори (2)


Ако искате да препратите към основния етап, трябва да изчакате, докато вашият обект бъде добавен към етапа, преди да можете да го препратите.

Може да изглежда така:

public function DetailView()
{
     addEventListener( Event.ADDED_TO_STAGE, onAddedToStage );
}

protected function onAddedToStage( event:Event ):void 
{
     tracker = new GATracker( this, "UA-WATEVER", "AS3", true );  
     removeEventListener( Event.ADDED_TO_STAGE, onAddedToStage );
}

Друг подход към това е прослушване на събитието ENTER_FRAME и в манипулатора проверка за ненулева стойност за етапа, след което премахване на манипулатора и инициализиране на вашите променливи.

person JeremyFromEarth    schedule 07.07.2011
comment
Хм, значи stage ще бъде дефинирано, когато го предам? Опитвам това сега. - person meder omuraliev; 07.07.2011
comment
Все пак не трябва да преминавате етап през него, все пак трябва да преминете това. Вътре в GATracker ще се опита да осъществи достъп до етапния обект на всичко, което подадете, така че в този пример ще се опита да осъществи достъп до this.stage.stage - person shanethehat; 07.07.2011
comment
@shanethehat, добра гледна точка, не бях запознат с вътрешността на GATracker, предоставяйки само представа кога етапният обект е наличен, актуализирах фрагмента - person JeremyFromEarth; 07.07.2011

Проблемът е, че вашият клас обект не е на сцената, когато се опитвате да инициализирате тракера. Разглеждайки източника за GATracker, препратката към this, която подавате, се използва за получаване на swf url от обекта loaderInfo на етапа: Ред 218.

Това ще се провали, ако какъвто и displayObject да подадете, където в момента използвате this, не е на сцената:

//_display contains a reference to the first property from the constructor
_env.url = _display.stage.loaderInfo.url;

Решенията са или:

  1. както предлага jeremynealbrown, за да добавите слушател за ADDED_TO¬STAGE и да инициирате вашия тракер само в този момент.
  2. прехвърлете препратка към класа на обект, който вече е на сцената, и използвайте тази препратка вместо this. Обхватът, който предавате за този първи параметър, е без значение, докато обектът е на сцената.
person shanethehat    schedule 07.07.2011