UI5

Dialog 매번 새로 만든다면? — Fragment 재사용 패턴 #shorts #SAP #UI5

Fragment란 무엇인가

UI5에서 Fragment는 자체 Controller를 갖지 않는 순수 UI 조각입니다. View와 동일한 XML 문법을 사용하지만, 독립적인 컨트롤러가 없기 때문에 호출하는 View의 Controller에 이벤트 핸들러를 위임합니다. Dialog, Popover, 메뉴, 폼 등 여러 화면에서 재사용되거나 조건부로만 등장하는 UI를 분리할 때 적합합니다.

비유하자면 Fragment는 레고 블록입니다. 한 번 만들어 두면 어떤 View에서도 Fragment.load()로 불러와 끼워 맞출 수 있습니다.

Dialog를 Fragment로 분리하는 이유

  • View 비대화 방지 — 메인 View XML 안에 Dialog까지 선언하면 파일이 빠르게 길어지고, 초기 렌더 트리에 불필요한 컨트롤이 포함됩니다.
  • 재사용성 — 같은 확인 Dialog를 여러 화면에서 호출하는 경우, Fragment 한 개로 일원화할 수 있습니다.
  • Lazy loading — 사용자가 버튼을 누른 시점에만 Dialog를 인스턴스화하여 초기 로드 비용을 줄일 수 있습니다.

Fragment 선언 (XML)

루트 엘리먼트는 core:FragmentDefinition이며, 그 안에 sap.m.Dialog를 배치합니다. Dialog의 버튼 press 핸들러는 호출 측 Controller의 메서드를 점(.) 표기로 참조합니다.

<!-- view/fragment/OrderDialog.fragment.xml -->
<core:FragmentDefinition xmlns="sap.m" xmlns:core="sap.ui.core">
  <Dialog title="주문 확인" id="orderDialog">
    <content>
      <Text id="orderMessage" text="{/orderMessage}" />
    </content>
    <beginButton>
      <Button text="확인" press=".onConfirm" />
    </beginButton>
  </Dialog>
</core:FragmentDefinition>

Controller에서 Fragment 로드 (lazy 패턴)

핵심은 한 번만 로드해서 인스턴스를 보관하는 것입니다. 매번 Fragment.load()를 호출하면 Dialog 인스턴스가 누적되어 메모리 누수와 ID 충돌이 발생할 수 있습니다. 첫 호출 시 생성한 객체를 this._oDialog에 캐싱하고, 이후에는 open()만 호출하는 패턴이 일반적으로 권장됩니다.

sap.ui.define([
  "sap/ui/core/mvc/Controller",
  "sap/ui/core/Fragment"
], function (Controller, Fragment) {
  "use strict";
  return Controller.extend("myapp.controller.Main", {
    onOpenDialog: async function () {
      if (!this._oDialog) {
        this._oDialog = await Fragment.load({
          id: this.getView().getId(),
          name: "myapp.view.fragment.OrderDialog",
          controller: this
        });
        this.getView().addDependent(this._oDialog);
      }
      this._oDialog.open();
    },
    onConfirm: function () {
      this._oDialog.close();
    }
  });
});

addDependent()를 호출하면 Fragment가 View의 모델/생명주기를 자연스럽게 상속받아 별도 모델 바인딩 작업이 줄어듭니다.

Fragment 내 컨트롤 접근 (Fragment.byId)

Fragment.load 시점에 id 옵션으로 View ID를 prefix로 부여하면, 컨트롤 ID가 viewId--orderDialog 형태로 네임스페이스화됩니다. Controller에서는 this.byId()로 안전하게 접근할 수 있습니다.

// View ID prefix가 자동 적용된 경우
var oText = this.byId("orderMessage");
oText.setText("주문이 정상 처리되었습니다.");

// Fragment 전용 ID로 직접 조회하려면
var oDialog = sap.ui.core.Fragment.byId(this.getView().getId(), "orderDialog");

같은 Fragment를 여러 View에서 재사용할 때는 반드시 호출 측 View ID를 prefix로 넘겨야 ID 충돌을 피할 수 있습니다.

핵심 한 줄

Dialog는 매번 새로 만들지 말고, Fragment로 분리한 뒤 Controller에서 Fragment.load()로 한 번만 로드해 캐싱하고 재사용하세요.

댓글 0

아직 댓글이 없습니다.