Flex 4: доступ к общедоступному методу в основном приложении из компонента - PullRequest
1 голос
/ 13 сентября 2010

Мне нужно иметь возможность вызывать метод из компонента, расположенного под основным приложением во Flex 4. Может кто-нибудь сказать мне, пожалуйста, как это сделать без использования FlexGlobals, пожалуйста?

Пример кода прилагается.Заранее спасибо.

// TestApp.mxml (application)
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
                       xmlns:s="library://ns.adobe.com/flex/spark" 
                       xmlns:mx="library://ns.adobe.com/flex/mx"
                       creationComplete="initApp()">
    <fx:Script>
        <![CDATA[
            import com.TestComp;

            import mx.managers.PopUpManager;

            public function myMethod():void
            {
                // do something
            }

            protected function initApp():void
            {
                var popUp:TestComp = new TestComp();

                PopUpManager.addPopUp(popUp, this, true);
            }
        ]]>
    </fx:Script>
</s:WindowedApplication>

// TestComp.mxml (component)
<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" 
         xmlns:s="library://ns.adobe.com/flex/spark" 
         xmlns:mx="library://ns.adobe.com/flex/mx"
         width="400" height="300">
    <fx:Script>
        <![CDATA[
            private function doSomething(event:MouseEvent):void
            {
                // call to myMethod() in TestApp.mxml
            }
        ]]>
    </fx:Script>
    <s:Button click="doSomething(event)" label="Click Me"/>
</s:Group>

Ответы [ 3 ]

2 голосов
/ 13 сентября 2010

Это плохой дизайн.Вы должны предоставить функцию обратного вызова или прослушиватель событий.

// TestComp.mxml

<mx:Metadata>
  [Event(name="doSomethingEvent", type="flash.events.Event")]
</mx:Metadata>

<mx:Script><![CDATA[

  private function doSomething(event:MouseEvent):void
  {
    this.dispatchEvent(new Event("doSomethingEvent"));
  }

]]></mx:Script>

// TestApp.mxml
protected function initApp():void
{
  var popUp:TestComp = new TestComp();
  popUp.addEventListener("doSomethingEvent", myMethod);
  PopUpManager.addPopUp(popUp, this, true);
}

private function myMethod(event: Event): void
{
  // do something
}

И это пример обратного вызова:

// TestComp.mxml

public var doSomethingCallback: Function;

private function doSomething(event:MouseEvent):void
{
  doSomethingCallback.call();
}

// TestApp.mxml
protected function initApp():void
{
  var popUp:TestComp = new TestComp();
  popUp.doSomethingCallback = myMethod;
  PopUpManager.addPopUp(popUp, this, true);
}

private function myMethod(): void
{
  // do something
}
1 голос
/ 13 сентября 2010

Самый простой вариант?

Извлеките обработчик щелчков из кнопки в TestComp.

В вашем главном приложении добавьте прослушиватель в TestComp (если он является прямым потомком основного приложения) или в себя (если TestComp находится ниже по списку отображения) для MouseEvent.CLICK. В обработчике проверьте, является ли цель события TestComp либо через ==, если у вас есть прямая ссылка, либо через "is", если нет.

Это наименьшее количество усилий из того, что у вас есть сейчас, все еще зависит от (пузырящихся) событий и является более "правильным"

0 голосов
/ 13 сентября 2010

Я согласен с splash, что это плохой дизайн, но следующее должно работать

//in TestApp
protected function initApp():void
{
  var popUp:TestComp = new TestComp(this);
  PopUpManager.addPopUp(popUp, this, true);
}

//in TestComp
private var app:TestApp;

public function TestComp(app:TestApp)
{
  this.app = app;
}

private function doSomething(event:MouseEvent):void
{
  // call to myMethod() in TestApp.mxml
  app.myMethod();
}

, или вы могли бы сделать это так

//in TestApp
protected function initApp():void
{
  var popUp:TestComp = new TestComp(this);
  popUp.addEventListener( 'test' , eventListener );
  PopUpManager.addPopUp(popUp, this, true);
}
private function eventListener(event:Event):void
{ 
   //in which case myMethod doesn't need to be public
   myMethod();
}

//in TestComp
private function doSomething(event:MouseEvent):void
{
  dispatchEvent( new Event('test') );
}
...