# 이벤트 표시 및 템플릿 사용자 지정

## Content

항목 템플릿과 CSS를 사용하면 원본 항목을 변경하지 않고도 이벤트 콘텐츠의 표시 방식을 제어할 수 있습니다. 템플릿은 표시 기능에 집중하고, 편집과 저장은 스케줄러와 바인딩된 컬렉션을 통해 처리하세요.

![항목템플릿](https://gcdocumentsitekrblob.blob.core.windows.net/document-site-files/images/8ecc18d2-feec-4d15-bd72-3d98a7b4cefa/11-1-20261019.4befac.png)

## 항목 템플릿 만들기

활성 `definition`의 `itemTemplate`에 함수를 할당합니다. 이 함수는 템플릿 컨텍스트를 전달받고 각 이벤트 조각 내부에 렌더링할 콘텐츠를 반환합니다.

```ts
const escapeHtml = (value: unknown) => String(value ?? '')
  .replaceAll('&', '&amp;')
  .replaceAll('<', '&lt;')
  .replaceAll('>', '&gt;')
  .replaceAll('"', '&quot;')
  .replaceAll("'", '&#39;');

scheduler.definition.itemTemplate = context => `
  <div class="appointment-title">${escapeHtml(context.item.subject)}</div>
  <div class="appointment-location">${escapeHtml(context.item.location)}</div>
`;
```

스케줄러는 반환된 문자열을 이벤트 요소의 `innerHTML`에 직접 할당합니다. 따라서 사용자 입력이나 외부 서비스에서 가져온 값은 이스케이프 처리해야 합니다. 이를 처리하지 않으면 HTML이 삽입되어 XSS 공격에 노출될 수 있습니다.
이벤트 내부에 표시할 콘텐츠만 반환하고, 별도의 래퍼 요소는 반환하지 마세요. 이벤트를 감싸는 요소와 상호작용 상태는 스케줄러가 직접 생성하고 관리합니다.

## 템플릿 컨텍스트 사용

애플리케이션에서 리소스 또는 충돌 정보가 필요한 경우 스케줄러가 제공하는 템플릿 컨텍스트를 사용하세요.

```ts
scheduler.definition.itemTemplate = context => {
  const item = context.item;
  const conflicts = context.conflicts ?? [];
  const conflictClass = conflicts.length > 0 ? ' has-conflict' : '';

  return `<div class="appointment${conflictClass}">
    <strong>${escapeHtml(item.subject)}</strong>
    <span>${conflicts.length} conflict(s)</span>
  </div>`;
};
```

전체 `SchedulerItemTemplateContext` 타입과 사용 중인 스케줄러 버전에서 제공하는 필드는 API Reference를 참조하세요.

`context.item`은 렌더링된 이벤트가 아니라 `itemsSource`의 원본 항목입니다. 실제 데이터에서 사용하는 속성명을 읽으세요. `eventFields`를 통해 `subject: 'title'`처럼 필드를 매핑했다면 `context.item.title`을 사용해야 합니다.

## 템플릿은 표시 용도로만 사용

DOM 조각을 읽어 이벤트를 식별하는 데 템플릿을 사용하지 마세요. 하나의 원본 항목이 여러 조각으로 렌더링될 수 있으며, 뷰, 날짜, 리소스 또는 시간대가 변경되면 해당 조각이 다시 생성될 수 있습니다. 명령 처리 및 저장 작업에는 스케줄러 이벤트, `getEvents` 또는 히트 테스트를 사용하여 원본 항목을 확인하세요.
스케줄러는 뷰를 새로 고칠 때마다 이벤트 요소를 다시 생성하므로 템플릿 내부에 이벤트 핸들러를 연결하지 마세요. 템플릿 요소에 연결한 핸들러는 다음 렌더링 시 사라집니다. 대신 스케줄러 호스트에서 이벤트 위임을 사용하고, 핸들러 내에서 원본 항목을 확인하세요.

## 런타임에 템플릿 변경

각 뷰에는 자체 `definition`이 있으며, 각 정의에는 자체 `itemTemplate`이 있습니다. 템플릿을 변경하려면 새 템플릿을 포함하는 정의를 생성하고 이를 스케줄러에 할당하세요.
`scheduler.definition`은 복사본을 반환하므로 반환된 객체의 속성을 변경해도 적용되지 않습니다. 새 정의를 생성하고 객체 전체를 다시 할당하세요.
여러 정의에서 동일한 템플릿을 사용해야 한다면 함수를 한 번만 생성한 다음 각 정의에 설정하세요.
정의를 할당하면 스케줄러가 무효화되고 자동으로 다시 렌더링됩니다. 변경 사항을 즉시 반영해야 하는 경우에만 `refresh()`를 호출하세요.

```ts
const definition = {
  ...scheduler.definition,
  itemTemplate: compactMode
  ? context => `<strong>${escapeHtml(context.item.subject)}</strong>`
  : context => `<strong>${escapeHtml(context.item.subject)}</strong><br>${escapeHtml(context.item.location)}`,
};
scheduler.definition = definition;
scheduler.refresh();
```