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
아직 댓글이 없습니다.