아직도 setItems? Aggregation Binding 끝 #shorts #SAP #UI5

Moderator

아직도 수동 setItems 쓰시나요?

List에 데이터를 채우려고 forEach 돌리며 addItem 하고 계신가요? 데이터가 바뀔 때마다 removeAllItems → 다시 채우기를 반복하면 코드가 금세 지저분해집니다. UI5는 이런 반복을 Aggregation Binding으로 한 줄에 끝낼 수 있도록 설계되어 있습니다.

수동 방식의 문제점

아래는 흔히 보는 안티패턴입니다. 모델이 갱신될 때마다 List를 비우고 다시 채워야 하며, 정렬/필터/그룹핑까지 직접 구현해야 합니다.

// 권장하지 않는 패턴
const oList = this.byId("productList");
oList.removeAllItems();
aProducts.forEach((p) => {
  oList.addItem(new StandardListItem({
    title: p.name,
    description: p.price
  }));
});

데이터가 1만 건이면 DOM 조작 비용도 그만큼 늘어납니다. 모델 변경 이벤트도 직접 구독해야 하죠.

Aggregation Binding 적용

items aggregation에 path와 template을 지정하면, 모델의 배열 각 요소마다 template이 자동 복제됩니다. 모델이 바뀌면 List도 알아서 갱신됩니다.

<List id="productList"
      items="{/products}">
  <StandardListItem
      title="{name}"
      description="{price}"
      icon="{icon}" />
</List>

Controller에서는 JSONModel만 세팅하면 끝입니다.

const oModel = new JSONModel({
  products: [
    { name: "Keyboard", price: "49 EUR" },
    { name: "Mouse",    price: "19 EUR" }
  ]
});
this.getView().setModel(oModel);

factory 함수로 동적 template

아이템 타입에 따라 다른 컨트롤을 그려야 한다면 factory를 사용합니다. template 하나로 부족할 때 유용합니다.

oList.bindItems({
  path: "/products",
  factory: (sId, oCtx) => {
    return oCtx.getProperty("onSale")
      ? new ObjectListItem({ title: "{name}", number: "{price}" })
      : new StandardListItem({ title: "{name}" });
  },
  sorter: new Sorter("name"),
  filters: [new Filter("price", "GT", 10)]
});

sorter, filters, groupHeaderFactory까지 선언적으로 붙일 수 있어 수동 구현 대비 코드량이 크게 줄어듭니다.

핵심 한 줄

List를 채우는 일은 UI5에게 맡기고, 개발자는 Model만 관리하세요.