UI5

직접 호출 없이 — EventBus 30초 만에 컴포넌트 통신 #shorts #SAP #UI5

▶ YouTube에서 보기

EventBus로 컴포넌트를 연결하는 이유

SAP UI5 앱이 커질수록 컴포넌트 간 데이터 흐름이 복잡해집니다. 한 뷰의 변경이 다른 뷰에 반영되어야 할 때, 직접 컨트롤러를 참조하거나 부모 컨트롤러를 통해 중계하는 방식은 의존성을 만들어 유지보수를 어렵게 합니다. UI5 EventBus를 사용하면 컴포넌트 간 직접 의존성 없이 30초 만에 통신 채널을 구축할 수 있습니다.

구조: 발행자(Publisher)와 구독자(Subscriber)

// 앱 구조
// - MasterView: 상품 목록 (Publisher)
// - DetailView: 상품 상세 (Subscriber)
// - CartView: 장바구니 (Subscriber)
// → 상품 선택 시 DetailView와 CartView 모두 업데이트

// EventBus 접근: 컴포넌트 레벨 (앱 내부 통신)
const oEventBus = this.getOwnerComponent().getEventBus();

// 글로벌 레벨 (Launchpad 앱 간 통신)
const oGlobalBus = sap.ui.getCore().getEventBus();

30초 구현: 상품 선택 이벤트

// Step 1 (10초): MasterController — 이벤트 발행
onProductSelect: function(oEvent) {
  const oContext = oEvent.getSource().getBindingContext();
  const oProduct = oContext.getObject();

  // EventBus로 이벤트 발행
  this.getOwnerComponent().getEventBus().publish(
    "Catalog",        // 채널
    "productSelected", // 이벤트
    {                  // 페이로드
      productId: oProduct.productId,
      productName: oProduct.name,
      price: oProduct.price,
      imageUrl: oProduct.imageUrl
    }
  );
}
// Step 2 (10초): DetailController — 구독 등록 + 해제
onInit: function() {
  this.getOwnerComponent().getEventBus().subscribe(
    "Catalog",
    "productSelected",
    this._onProductSelected,
    this
  );
},

_onProductSelected: function(sChannel, sEvent, oData) {
  // 상품 상세 로드
  const oModel = this.getView().getModel("detail");
  oModel.setProperty("/", oData);

  // 상세 뷰 활성화
  this.getView().setVisible(true);
},

onExit: function() {
  this.getOwnerComponent().getEventBus().unsubscribe(
    "Catalog",
    "productSelected",
    this._onProductSelected,
    this
  );
}
// Step 3 (10초): CartController — 동일 이벤트 구독 (다른 반응)
onInit: function() {
  this.getOwnerComponent().getEventBus().subscribe(
    "Catalog",
    "productSelected",
    this._previewInCart,
    this
  );
},

_previewInCart: function(sChannel, sEvent, oData) {
  // 장바구니에 미리보기 표시
  this.byId("cartPreview").setVisible(true);
  this.byId("cartProductName").setText(oData.productName);
  this.byId("cartProductPrice").setText(
    oData.price.toLocaleString() + " 원"
  );
},

onExit: function() {
  this.getOwnerComponent().getEventBus().unsubscribe(
    "Catalog",
    "productSelected",
    this._previewInCart,
    this
  );
}

페이로드 설계 원칙

// 좋은 페이로드: 필요한 데이터만 포함, 편평한 구조
oEventBus.publish("Orders", "created", {
  orderId: "SO-001",
  customerId: "CUST-042",
  amount: 50000,
  currency: "KRW"
});

// 나쁜 페이로드: 전체 DOM 참조 또는 복잡한 객체
oEventBus.publish("Orders", "created", {
  oButton: this.byId("submitBtn"),  // DOM 참조 — 절대 금지
  oModel: this.getView().getModel() // 모델 참조 — 메모리 누수 위험
});

EventBus 이벤트 목록 관리

// 이벤트 상수를 별도 파일로 관리 (EventConstants.js)
sap.ui.define([], function() {
  "use strict";
  return {
    CHANNEL: {
      CATALOG: "Catalog",
      ORDERS:  "Orders",
      CART:    "Cart",
      APP:     "App"
    },
    EVENT: {
      PRODUCT_SELECTED: "productSelected",
      ORDER_CREATED:    "orderCreated",
      CART_UPDATED:     "cartUpdated",
      USER_LOGGED_OUT:  "userLoggedOut"
    }
  };
});

// 사용 시
const C = EventConstants;
oEventBus.publish(C.CHANNEL.CATALOG, C.EVENT.PRODUCT_SELECTED, oData);
oEventBus.subscribe(C.CHANNEL.ORDERS, C.EVENT.ORDER_CREATED, handler, this);

EventBus vs 공유 모델 선택 기준

  • 일회성 액션 알림: EventBus
  • 여러 뷰가 동일 데이터를 실시간으로 반영: 공유 JSONModel
  • 컴포넌트 간 느슨한 결합 유지: EventBus
  • Form 데이터처럼 연속적으로 바뀌는 데이터: 공유 모델

공식 문서

UI5 EventBus 전체 API는 ui5.sap.com EventBus API에서 확인하세요. UI5 컴포넌트 통신 패턴은 Cross-Component Communication 문서에서 다룹니다.

댓글 0

아직 댓글이 없습니다.