2009-10-01 5 views
0

Я вижу преимущество асинхронных команд (ожидание ответов сервера ...), но в моем приложении flex это создает мне больше проблем, чем что-либо. Вот что я хочу:make cairngorm команды ВСЕГДА работают синхронно

Каждая команда выполняется только после того, как предыдущий вернулся (в результате или функция ошибки)

И я хотел бы сделать это так же легко, как это возможно .. кстати GUI должен стать (возможно, сообщение ожидания), пока выполняется длинная команда (я могу показать сообщение ожидания в функции выполнения и удалить его в функции сбоя или результата.)

любая идея?

+0

Хорошо, я открыл щедрость. Пожалуйста, прочитайте комментарий к первому ответу, чтобы лучше понять мою проблему. – luca

ответ

0

я достиг этого за счет расширения CairngormEvent класса и добавляя два свойства:

package control.events 
{ 
    import com.adobe.cairngorm.control.CairngormEvent; 

    public class AbstractCairngormEvent extends CairngormEvent 
    { 
     public var successHandler:Function; 

     public var failureHandler:Function; 

     public function AbstractCairngormEvent(type:String) 
     { 
      super(type); 
     } 
    } 
} 

и создание нового класса в качестве базы для всех команд, который реализует ICommand:

package control.commands 
{ 
    import com.adobe.cairngorm.commands.ICommand; 
    import com.adobe.cairngorm.control.CairngormEvent; 

    import control.events.AbstractCairngormEvent; 

    /* This class is a base for all Commands. It allows the user to set callback 
     functions for successful completion and/or failure of the Command logic (i.e. 
     a WebService call). */ 
    public class CairngormCommand implements ICommand 
    { 
     private var successHandler:Function; 

     private var failureHandler:Function; 

     public function execute(event:CairngormEvent):void 
     { 
      if (event is AbstractCairngormEvent) 
      { 
       var commandEvent:AbstractCairngormEvent = 
        event as AbstractCairngormEvent; 

       successHandler = commandEvent.successHandler; 

       failureHandler = commandEvent.failureHandler; 
      } 
     } 

     public function notifyCallerOfSuccess():void 
     { 
      if (successHandler != null) 
       successHandler.call(this); 
     } 

     public function notifyCallerOfFailure():void 
     { 
      if (failureHandler != null) 
       failureHandler.call(this); 
     } 
    } 
} 

Затем в каждой Command Class, когда необходимая логика завершена или возникает ошибка/сбой, я вызываю соответствующую функцию в базовом классе CairngormCommand. Вот пример:

// Something like this would be in your view: 

private function callSomeWebService():void { 
    var event:WebServiceEvent = new WebServiceEvent(); 

    myEvent.successHandler = callMyEventSuccessHandler; 

    myEvent.failureHandler = callMyEventFailureHandler; 
} 

private function callMyEventSuccessHandler():void { 
    Alert.show("SUCCESS!!!"); 
} 

private function callMyEventFailureHandler():void { 
    Alert.show("FAILURE!!!"); 
} 


// Here is the Event in your Controller: 

package control.events 
{ 
    import control.events.AbstractCairngormEvent; 

    public class WebServiceEvent extends AbstractCairngormEvent 
    { 
     public static var EVENT_ID:String = "webService"; 

     public function WebServiceEvent() 
     { 
      super(EVENT_ID); 
     } 
    } 
} 

// And here is the Command in your Controller: 

package control.commands 
{ 
    import com.adobe.cairngorm.control.CairngormEvent; 

    import control.commands.CairngormCommand; 
    import control.events.WebServiceEvent; 

    public class WebServiceCommand extends CairngormCommand 
    { 
     override public function execute(event:CairngormEvent):void 
     { 
      super.execute(event); 

      ... // Call WebServices 
     } 
     ... 

     private function webServiceResultHandler():void 
     { 
      // Handle results 
      ... 

      notifyCallerOfSuccess(); 
     } 

     private function webServiceFaultHandler():void 
     { 
      // Handle fault 
      ... 

      notifyCallerOfFailure(); 
     } 
    } 
} 

Я использую это ЭКСКЛЮЗИВНО в своих приложениях Cairngorm. Лучшая часть, если вам не нужно иметь обратный вызов для успеха и/или неудачи, вы можете просто оставить эти свойства вне экземпляра события и просто отправить событие.

Пример загрузки данных, необходимых для отображения перед загрузкой дисплея:

<?xml version="1.0" encoding="utf-8"?> 
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 
    usePreloader="false" initialize="initializeHandler();"> 
    <mx:Script> 
     <![CDATA[ 
      import control.events.InitializeApplicationEvent; 

      private function initializeHandler():void 
      { 
       initializeApplication(); 
      } 

      private function initializeApplication():void 
      { 
       var event:InitializeApplicationEvent = 
        new InitializeApplicationEvent(); 

       event.successHandler = initializationSuccessHandler; 

       event.dispatch(); 
      } 

      private function initializationSuccessHandler():void 
      { 
       applicationContainer.visible = true; 
      } 
     ]]> 
    </mx:Script> 

    <control:Services xmlns:control="control.*" /> 

    <control:Controller xmlns:control="control.*" /> 

    <view:ApplicationContainer xmlns:view="view.*" id="applicationContainer" 
     width="100%" height="100%" visible="false" /> 
</mx:Application> 

InitializeApplicationCommand (обратите внимание, как вы можете приковать события и звонящих столько раз, сколько вы хотите):

package control.commands 
{ 
    import com.adobe.cairngorm.control.CairngormEvent; 

    import control.events.GetEvenMoreDataEvent; 
    import control.events.GetSomeDataEvent; 
    import control.events.GetSomeMoreDataEvent; 
    import control.events.InitializeApplicationEvent; 

    public class InitializeApplicationCommand extends CairngormCommand 
    { 
     override public function execute(event:CairngormEvent):void 
     { 
      super.execute(event); 

      getSomeData(); 
     } 

     private function getSomeData():void 
     { 
      var event:GetSomeDataEvent = new GetSomeDataEvent(); 

      event.successHandler = getSomeMoreData; 

      event.failureHandler = errorHandler; 

      event.dispatch(); 
     } 

     private function getSomeMoreData():void 
     { 
      var event:GetSomeMoreDataEvent = new GetSomeMoreDataEvent(); 

      event.successHandler = getEvenMoreData; 

      event.failureHandler = errorHandler; 

      event.dispatch(); 
     } 

     private function getEvenMoreData():void 
     { 
      var event:GetEvenMoreDataEvent = new GetEvenMoreDataEvent(); 

      event.successHandler = notifyCallerOfSuccess; 

      event.failureHandler = errorHandler; 

      event.dispatch(); 
     } 

     private function errorHandler():void 
     { 
      alert.show("error"); 
     } 
    } 
} 
+0

FYI, я построил эту логику на основе информации, которую я видел где-то в Интернете - я забыл, где, или я бы дал им кредит! –

+0

ok .. так что у меня есть функция, называемая в конце команды .. но посмотрите на эту ситуацию: у меня есть событие, отправленное при событии preinitialize, чья команда загружает мою модель. Затем эти данные используются для создания интерфейса. Я должен остановить выполнение до тех пор, пока команда не вернется, иначе интерфейс будет продолжать строить без данных! Я хочу, чтобы отправить событие, а затем дождаться окончания соответствующей команды, можно ли это сделать? – luca

+0

Именно так я использую эту функциональность !!! Я отредактирую ответ выше, чтобы показать вам ... –