Rich UI의 동적 로드

모든 Rich UI 핸들러를 단일 HTML 파일에 배치하는 대신 런타임 시 Rich UI 핸들러 코드에 대한 다운로드를 제어할 수 있습니다. 대형 애플리케이션의 경우 확장성과 성능에 큰 이점을 얻을 수 있습니다.

각 동적 로드는 비동기입니다. 로드가 완료되면 응답할 listener 함수를 코딩하고, 로드가 완료될 때까지 계속해서 웹 페이지와 상호작용합니다.

다음 두 가지 백그라운드 방법으로 한 핸들러가 다른 핸들러를 참조할 수 있음을 고려해 보십시오.
  • 유형 참조 방법은 다음 예와 같습니다.
    // a simple declaration
    mySecondary Secondary{};
    
    // the as keyword, in a usage described later in this topic
    mySecondary Secondary = theHandler as Secondary;
  • 런타임 시에만 해석되는 따옴표 안의 문자열 방법은 다음 예와 같습니다.
    handler MainHandler type RUIhandler {onConstructionFunction = start }
    
       function start() 
       
       // Load the first page    
       DynamicLoader.loadHandler("myPkg.Secondary");
    end
핸들러가 런타임 시에만 애플리케이션 서버로부터 로드되도록 하려면 다음과 같이 하십시오.
  • DynamicLoader.loadHandler 함수를 호출하십시오.
  • EGL 배치 디스크립터를 구성하십시오. 사용자 목적은 두 가지입니다.
    • DynamicLoader.loadHandler 호출에서 이름 지정된 핸들러를 식별합니다. 인수로 사용된 문자열은 런타임 시에만 의미가 있습니다. EGL 배치 디스크립터에서 동일한 핸들러를 식별하여 핸들러가 런타임 로드에 사용 가능하는지 확인하십시오.
    • 한 번에 다운로드되는 즉시 다운로드 코드 로직(예: 처음 다운로드된 HTML 파일)에 핸들러가 포함되지 않도록 하십시오. 한 핸들러가 세 번째 핸들러를 동적으로 로드하는 두 번째 핸들러를 로드하는 경우 두 번째 핸들러의 파트와 위젯만이 두 번째 핸들러와 함께 로드됩니다. 세 번째 핸들러는 즉시 다운로드되는 코드에 없습니다.

유형 참조를 지정하고 동적 로딩에 대한 EGL 배치 디스크립터를 구성하지 않은 경우 유형 참조로 인해 참조되는 핸들러가 즉시 다운로드되는 코드에 포함되게 됩니다.

나중에 설명되는 코드 예에서 사용자 코드가 동적으로 로드되는 핸들러의 필드 또는 함수를 직접 액세스하는 경우 유형 참조가 필수입니다. 그러나 사용자 코드가 동적으로 로드되는 핸들러의 initialUI 특성에 지정된 위젯 배열만 액세스하는 경우 유형 참조가 필요하지 않습니다.

동적 로드는 ModuleLoaderService라는 EGL 전용 서비스에 의해 런타임 시에 핸들링됩니다. 이 서비스를 변경하지 마십시오. 이 서비스는 제품의 이후 버전에서 변경될 수 있는 내부 세부사항을 처리합니다.

동적 로더에 대한 동일한 사용은 “EGL Dojo 위젯”을 참조하십시오. 특히 GalleryDynamicLoading.egl 파일을 참조하십시오.

DynamicLoader 함수

DynamicLoader 라이브러리에는 호출에 응답하는 listener 함수(나중에 설명)와 함께 다음 함수가 있습니다.
  • loadHandler (handlerName String in)

    이 함수는 핸들러를 로드합니다.

    handlerName
    동적으로 로드할 핸들러의 완전한 이름(이전에 표시된 예와 같음)
  • loadHandlerNoInstantiation (handlerName String in)

    이 함수는 핸들러 인스턴스가 아닌 핸들러 유형 정의를 로드합니다. 더 나은 런타임 성능을 위해 이 함수를 사용할 수 있습니다. 예를 들어 애플리케이션에서 핸들러 유형을 사용할 수 있지만 핸들러가 필요한 메뉴 항목을 클릭하는 경우에만 핸들러를 작성하려고 할 수 있습니다.

    handlerName
    동적으로 로드할 핸들러의 완전한 이름입니다.
  • unloadHandler (handlerName String in)

    이 함수는 핸들러를 로드 해제하지만 해당 핸들러의 인스턴스를 영구 삭제하지는 않습니다. 애플리케이션이 종료될 때까지 사용 가능한 EGL 라이브러리는 로드 해제할 수 없습니다.

    다음 명령문이 true인 경우 메모리에서 핸들러 인스턴스를 제거할 수 없습니다.
    • 메모리에서 제거되지 않는 다른 핸들러의 유형이 핸들러를 참조합니다.
    • “Rich UI Infobus”에 설명된 대로 핸들러는 Inforbus에 등록됩니다.

    대부분의 경우 메모리는 EGL 런타임 코드에 의해 해제됩니다. 그러나 “Rich UI 메모리 관리자” 주제에서 메모리 관리를 위한 더 많은 제어 방법에 대해 설명합니다.

    handlerName
    로드 해제할 핸들러의 완전한 이름입니다.
  • showDebugView()

    이 함수는 동적 로더 내부에서 발생하는 상황에 대한 세부사항을 표시합니다. 기본 핸들러의 on-construction 함수에서 이를 설정할 수 있습니다.

DynamicLoader 리스너 배열

DynamicLoader 라이브러리에서는 위임 파트에 해당하는 리스너를 코딩하고 해당 리스너를 배열에 지정하며 런타임 시 이벤트에 응답하는 방식의 메커니즘을 제공합니다. 다음은 사용 예입니다.
function start()
   // Set handler for the event that the page has been loaded
   DynamicLoader.loadDoneListeners ::= processLoadDone;

   DynamicLoader.loadHandler("myPkg.Secondary");
end

function processLoadDone (event HandlerLoadedEvent in)
   
   // attach the initialUI widgets to the current page.
   // this step does not require use of a type reference.
   div.children = event.initialUI;

   // access a function in the loaded handler
   theHandler any = event.theHandler;

   // the use of a handler (or other container) of type any requires
   // a type reference so that your code can directly access a field 
   // or function that is embedded in that container
   if (theHandler isa Secondary)
      p1 Page1 = theHandler as Secondary;
      p1.doTask();
   end
end
다음은 HandlerLoadedEvent 레코드 파트이며, 이는 processLoadDoneevent 매개변수에서 사용 가능한 항목을 식별합니다.
record HandlerLoadedEvent

   // The name of the handler
   name String;

   // The widgets defined by the Rich UI handler.
   initialUI Widget[];

   // A reference to the Rich UI handler
   theHandler any;
end
다음은 DynamicLoader 라이브러리에서 제공하는 리스너 및 관련 위임 파트입니다.
  • DynamicLoader.loadDoneListeners
    이 배열은 핸들러를 로드한 후 호출되는 리스너 세트를 지정합니다. 위임 파트는 다음과 같습니다.
    delegate
       LoadDoneListener (event HandlerLoadedEvent in)
    end
    event
    이전에 표시된 것과 같습니다. 그러나 리스너가 loadHandlerNoInstantiation 함수 호출에 대한 응답으로 실행 중인 경우 initialUI 매개변수는 비어 있는 배열을 받고 theHandler 매개변수는 널을 받습니다.
  • DynamicLoader.loadFailListeners
    이 배열은 로드에 실패한 경우 호출되는 리스너 세트를 지정합니다. 위임 파트는 다음과 같습니다.
    delegate
       LoadFailListener (handlerName string in, msg string in) 
    end
    handlerName
    로드에 실패한 핸들러의 완전한 이름입니다.
    msg
    오류 메시지입니다.
    예를 들어 다음과 같습니다.
    function start()
       DynamicLoader.loadFailListeners ::= processLoadFail;
       DynamicLoader.loadHandler("myPkg.Secondary");
    end
    
    Function processLoadFail (handlerName string in, msg string in)    
       Syslib.writeStdErr(handlerName + “ failed to load. ” + msg);
    end
  • DynamicLoader.loadInfoListeners
    이 배열은 동적 로더에서 호출되는 리스너 세트를 지정하고, 런타임 시 다운로드 및 로드 해제 동작을 추적하는 데 사용됩니다. 리스너 세트는 다운로드되거나 로드 해제된 모든 자원에 대해 한 번만 호출되며 다음 단위로 사용됩니다,
    • 파트
      • Rich UI 핸들러
      • 기본 핸들러
      • 위젯
      • 라이브러리(Rich UI 특성 라이브러리 포함)
      • 레코드
    • 기타 자원
      • JavaScript 포함 파일(글로벌하게 정의되거나 외부 유형에서 참조되는지에 상관 없음)
      • Rich UI 특성 라이브러리와 관련된 특성 파일
      • EGL 배치 디스크립터와 관련된 서비스 바인딩 파일
    위임 파트는 다음과 같습니다.
    delegate
       LoadInfoListener (handlerName string, resourceName string, 
                         code string, msg string)
    end
    handlerName
    load 또는 unload 함수에 전달된 핸들러의 완전한 이름입니다.
    resourceName
    다운로드되거나 로드 해제된 자원의 이름입니다.
    code
    다음 코드 중 하나이며, 각 코드는 정보 유형을 식별합니다.
    • DynamicLoader.INFO_LOAD는 자원이 로드되었음을 표시합니다.
    • DynamicLoader.INFO_UNLOAD는 자원이 로드 해제되었음을 표시합니다.
    • DynamicLoader.INFO_UNLOAD_SKIP은 자원이 로드 해제되지 않았음을 표시합니다(예: 자원이 라이브러리여서 로드 해제되지 않음).
    • DynamicLoader.INFO_DEBUG는 동적 로드로부터의 일반 메시지입니다.
    msg
    메시지입니다.
    예를 들어 다음과 같습니다.
    function start()
       DynamicLoader.loadInfoListeners ::= processLoadInfo;
       DynamicLoader.loadHandler("myPkg.Secondary");
    end
    
    function processLoadInfo (handlerName string, 
       resourceName string, code string, msg string)
       if (code == DynamicLoader.INFO_UNLOAD)
          Syslib.writeStdErr(resourceName + “ unloaded.”);
       end
    end

핸들러 인스턴스

다음과 같이 핸들러가 로드된 후 핸들러의 새 인스턴스를 작성할 수 있습니다.
function createPage1() returns (Secondary)
   anotherPage1 Secondary = new Secondary{};
   return(anotherPage1);
end
핸들러가 로드되기 전에 새 인스턴스를 작성하려고 하지 마십시오. 예를 들어 다음과 같습니다.
handler MainHandler type RUIhandler {onConstructionFunction = start }

   // error!
   anotherPage1 Page1 = new Secondary{};   
end

런타임 시 CSS 파일 사용을 위한 고려사항

EGL 배치자가 핸들러에 대한 HTML 파일을 작성하는 경우 이 파일에는 Rich UI 애플리케이션에서 사용되는 모든 CSS 파일 목록이 포함됩니다. CSS 파일은 동적으로 로드되지 않습니다.

CSS 정의에 대한 우선순위 순서는 다음과 같습니다.
  • 최상위 레벨은 맨 위에 있는 핸들러의 정의입니다.
  • 다음은 HTML 파일에 있는 다른 핸들러의 정의입니다.
  • 최하위 레벨은 동적으로 로드되는 핸들러의 정의입니다.

Rich UI 편집기의 미리보기 분할창 사용을 위한 고려사항

Rich UI 편집기의 미리보기 분할창에서 핸들러를 실행할 때 다음 규칙이 적용됩니다.
  • 워크벤치는 편집 중인 핸들러의 유형에 의해 참조되거나 두 번째 레벨 핸들러 중 하나에서 참조하는 핸들러의 유형에 의해 참조되는(세 번째, 네 번째 등 계속) 모든 자원이 포함된 HTML 파일을 임의의 참조 레벨로 빌드합니다.
  • 유형 참조가 아닌 문자열에 의해 식별되는 유일한 핸들러는 동적으로 로드되는 핸들러입니다.
미리보기 분할창에서 동적으로 로드되는 핸들러의 경우 다음 고려사항이 적용됩니다.
  • 동적으로 로드되는 핸들러에서 지정된 CSS 및 포함 파일은 미리보기 분할창에 사용할 수 없습니다. 편집 중인 핸들러 또는 편집 중인 핸들러의 유형 참조에 의해 직접 또는 간접으로 로드된 핸들러에서 해당 파일을 참조해야 합니다.
  • 참조하지 않는 경우에도 JavaScript 런타임 파일을 핸들링해야 합니다. 예를 들어 핸들러 A에서 EGL Dojo 위젯을 사용하지 않고 문자열에 의해서만 핸들러 B를 참조하는 경우와 핸들러 B에서 EGL Dojo 위젯을 사용하는 경우, 다음과 같이 Dojo 런타임 코드를 참조하도록 핸들러 A의 includeFile 특성을 설정해야 합니다.
    { includeFile = "config/includeDojo.html" }