Как сослаться на ссылку 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, которую вы передаете, используется для получения URL-адреса swf из объекта 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