플러그인 설명 / Master / Detail개발 매뉴얼로 돌아가기

Master / Detail 플러그인

Master / Detail · detailPlugin

상세 버튼 아래에 별도 ZixoGrid 인스턴스를 만들고 해당 부모의 하위 데이터를 표시합니다. 예제는 부모·상세 각각 100행을 사용합니다.

설치 함수: detailPlugin(config) · 해제 이름: detail

설정 속성 · 기본값

필수값은 해당 입력에서 반드시 제공하는 값입니다. 조건부 필수값은 설명에 적힌 기능을 사용할 때 필요합니다. 표시가 없는 옵션은 생략할 수 있으며 기본값을 사용합니다. 빈 문자열·누락과 0·false를 혼동하지 마세요.

설정 위치와 동작
설정기본값설명
field 필수값없음상세 버튼을 표시할 컬럼 field입니다. 보통 editable:false로 구성합니다.

상세 버튼을 표시할 부모 컬럼의 field를 지정합니다.

columns하위 컬럼 배열하위 그리드에 사용할 컬럼을 전달합니다.
rows없음rows(parentRow)가 로컬 하위 배열을 반환합니다.
loadRows없음loadRows(parentRow,{signal})이 하위 배열을 비동기 반환합니다. 조회 결과를 부모 키별로 캐시하며 로컬 rows보다 우선 사용합니다.

사용 순서

  1. 상세 버튼 컬럼을 부모 columns에 추가합니다.
  2. 하위 columns와 rows(parentRow) 또는 loadRows(parentRow,{signal})를 선언합니다.
  3. 상세 버튼을 누르면 별도 그리드가 생성됩니다. 같은 상세를 접거나 부모를 종료하면 하위 인스턴스를 정리합니다.

연결 API

플러그인 또는 연결된 Core API
호출동작
grid.toggleDetail(id)부모 행의 상세를 접거나 펼칩니다. 비동기 조회를 포함하며 Promise를 반환합니다.

필수값 grid.toggleDetail 인수: id

설치 · 해제 · Vue 3 수명주기

생성 시 plugins에 등록하거나, 아직 설치하지 않은 인스턴스에서 grid.install을 호출합니다. 같은 name은 중복 설치할 수 없습니다. 설정에 쓰는 데이터·함수는 아래 전체 예제 소스를 참고하세요.

grid.install(detailPlugin({
      field: 'detail',
      columns: [{ field: 'name', title: '하위 주문', width: 300 }],
      rows: createDetailRows,
    }));
grid.uninstall('detail'); // 플러그인 해제
// Vue 3 컴포넌트가 종료될 때
onBeforeUnmount(() => grid.destroy());

조회 AbortController를 취소하고 생성된 하위 그리드를 destroy합니다. 상세 렌더러·변환·render 리스너를 제거하고 이전 toggleDetail을 복원합니다. 재렌더/가상화 이탈 시에도 하위 인스턴스를 정리합니다.

관련 이벤트

  • render
  • error

이벤트 구독은 grid.on(name, (detail, grid) => {})를 사용합니다. 해제 함수 또는 grid.off로 구독을 정리하세요.

실행 예제 · 실제 원본

아래 소스는 examples/features/detail.js와 Vue 원본입니다. 해당 예제 경로를 기준으로 import하며, 행 데이터는 별도 파일을 함께 사용합니다.

JavaScript 전체 소스 · detail.js
import { ZixoGrid, detailPlugin } from '../../src/index.js';
import { rows, createDetailRows } from './detail.data.js';

const host = document.querySelector('#grid'),
  report = document.querySelector('#report');

const options = {
  rowKey: 'id',
  height: 360,
  rows: rows,
  columns: [
    { field: 'name', title: '주문', width: 240 },
    { field: 'qty', title: '수량', type: 'number', parse: Number },
    { field: 'price', title: '단가', type: 'number', parse: Number },
    { field: 'detail', title: '상세', editable: false },
  ],
  plugins: [
    detailPlugin({
      field: 'detail',
      columns: [{ field: 'name', title: '하위 주문', width: 300 }],
      rows: createDetailRows,
    }),
  ],
};

const grid = new ZixoGrid(host, options);

window.addEventListener('pagehide', () => grid.destroy(), { once: true });
grid.on(
  'validationerror',
  (detail) => (report.textContent = detail.error.message),
);

report.textContent = '상세 버튼으로 하위 그리드를 생성하고 접으면 해제합니다.';
Vue 3 전체 소스 · vue-detail.vue
<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue';
import { ZixoGrid, detailPlugin } from '../../src/index.js';
import { rows, createDetailRows } from './detail.data.js';

// Instance and DOM belong to this component, never to window or a global ID.
const gridHost = ref(null);
const message = ref('');

let grid;
let alive = true;

onMounted(() => {
  const options = {
    rowKey: 'id',
    height: 360,
    rows: rows,
    columns: [
      { field: 'name', title: '주문', width: 240 },
      { field: 'qty', title: '수량', type: 'number', parse: Number },
      { field: 'price', title: '단가', type: 'number', parse: Number },
      { field: 'detail', title: '상세', editable: false },
    ],
    plugins: [
      detailPlugin({
        field: 'detail',
        columns: [{ field: 'name', title: '하위 주문', width: 300 }],
        rows: createDetailRows,
      }),
    ],
  };

  grid = new ZixoGrid(gridHost.value, options);

  grid.on(
    'validationerror',
    (detail) => (message.value = detail.error.message),
  );

  message.value = '상세 버튼으로 하위 그리드를 생성하고 접으면 해제합니다.';
});
onBeforeUnmount(() => {
  alive = false;
  grid?.destroy(); // Cancels grid requests, removes events and releases plugins.
  grid = undefined;
});
defineExpose({ getGrid: () => grid });
</script>

<template>
  <main>
    <h1>Master / Detail</h1>

    <div ref="gridHost" class="vue-grid-host"></div>
    <div class="notes result" aria-live="polite">{{ message }}</div>
  </main>
</template>

제약 사항 · 주의할 동작

  • 하위 rowKey는 id이며 하위 그리드는 이 플러그인이 전달하는 columns/rows로 구성됩니다. 임의 하위 plugins 설정은 현재 제공하지 않습니다.
  • 상세 영역은 고정 높이 180px, 하위 그리드는 160px로 생성합니다.
  • lazy 조회 실패 시 error와 재시도를 사용하며 여러 동시 요청의 공유 상태 표시에 제한이 있습니다.

연결 기능 메뉴

Master / Detail · Tree / Detail lazy 요청

이 플러그인 상세 페이지 독립 열기 ↗ · 플러그인 설명 전체