문제

비동기 명령(서버 응답을 기다리는 중...)의 이점을 알고 있지만 내 Flex 앱에서는 무엇보다 더 많은 문제가 발생합니다.내가 원하는 것은 다음과 같습니다.

EVERY 명령은 이전 명령이 반환된 후에만 실행됩니다(결과 또는 결함 함수로).

그리고 가능한 한 쉽게하고 싶습니다 ..그런데 긴 명령이 실행되는 동안 GUI는 응답하지 않아야 합니다(대기 메시지일 수도 있음)(실행 함수에 대기 메시지를 표시하고 오류 또는 결과 함수에서 이를 제거할 수 있습니다.)

어떤 아이디어?

도움이 되었습니까?

해결책

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);
        }
    }
}

그런 다음 각 명령 클래스에서 필요한 논리가 완료되거나 오류/실패가 있는 경우 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");
        }
    }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top