Skip to content
On this page

트리

트리는 wijmo의 TreeView를 상속한 VmTreeView를 사용한다.

wijmo TreeView api

database에서 조회한 데이터는 열과 컬럼으로 된 리스트 형태인데, 트리를 구성하는 데이터는 상하 관계를 가진 계층구조 이어야 한다. 그리고 트리에서 추가, 수정한 데이터를 database에 저장하려면 계층구조를 리스트형태로 변환해야한다.

리스트 형태를 계층구조 형태로 변환하는데 필요한 리스트의 기준 프로퍼티 이름(PK에 해당), 상위 프로퍼티 이름, 자식 프로퍼티 이름을 props로 설정한다. 추가로 정렬순서와 명칭 키 이름을 설정할 수 있다.

조회한 리스트 데이터는 VmTreeViewsetData 함수로 입력하고, 수정된 데이터는 getSaveData 함수로 얻는다.

VmTree

template에는 VmTree를 사용한다.

  • Props

    • modelValue ? - TreeNode 선택한 트리노드. 데이터는 node.dataItem로 읽는다.
    • keyId - string 계층 구조로 변환할때 기준 프로퍼티 이름
    • keyNm - string 기준 키의 명칭에 해당하는 프로퍼티 이름. 노드에 표시될 텍스트값을 가진 프로퍼티 이름
    • keyParent : - string 계층 구조로 변환할때 상위 프로퍼티 이름
    • keyChild ? - string 계층 구조로 변환할때 자식 프로퍼티 이름. 기본값은 items
    • keySort ? - string 계층 구조에서의 정렬순서를 가진 프로퍼티 이름. sortSeq
    • editable ? - boolean 트리의 수정 가능여부로 선택한 노드에 추가, 수정, 삭제 아이콘이 표시된다.
    • editPlaceholder ? - string 트리 노드의 이름을 수정할때 표시할 placeholder
    • itemCreator ? - () => any 트리의 노드를 추가할때 제공할 데이터를 반환하는 함수
    • adding ? - () => boolean 노드 추가전 실행 할 함수. return false하면 추가하지 않는다.
    • added ? - () => void 노드 추가후 실행 할 함수.
    • editing ? - () => boolean 노드의 명칭을 수정 모드로 전환하기전에 실행 할 함수. return false하면 수정모드로 전환하지 않는다.
    • edited ? - () => void 노드의 명칭을 수정 모드로 전환 한 후애 실행 할 함수.
    • removing ? - () => boolean 노드 삭제전 실행 할 함수. return false하면 추가하지 않는다.
    • removed ? - () => void 노드 삭제후 실행 할 함수.
    • d ? - boolean 탭의 디버깅 정보표시
      이하는 wijmo TreeView의 Properties(https://www.grapecity.com/wijmo/api/classes/wijmo_nav.treeview.html)
    • allowDragging ? - boolean 드래그 가능여부. 기본값 true
    • autoCollapse ? - boolean 노드를 펼칠때 이웃한 다른 노드가 접힐지 여부. 기본값 false
    • expandOnClick ? - boolean 노드의 텍스트를 클릭하면 펼칠지 여부. 기본값 false
    • formatItem ? - (s: VmTreeView, e: FormatNodeEventArgs) => void 노드가 생성될때 표시될 모양을 변경한다. editabletrue이면 노드의 오른쪽 끝에 추가, 수정, 삭제 아이콘이 표시된다.
  • Emits

    • initialized - 트리가 초기화되면 호출된다. 파라미터의 트리 instance를 받아서 미리 선언한 트리변수에 할당한다.
    (e: 'initialized', vmTreeView: VmTreeView): void
    
  • 노드 모양 변경

    트리 생성시 노드의 html을 생성하는 함수를 작성하고 formatItem props로 설정한다.

    /**
     * formatItem을 설정하지 않으면 다음의 함수가 실행되서 html코드가 생성된다.
     * 기본 모양. 파란색 폴더모양 아이콘과 파란색 둥근박스
     */
    function defaultFormatItem(s: VmTreeView, e: FormatNodeEventArgs) {
      const el = e.element as HTMLDivElement
      el.innerHTML = '<span class="icon folder"></span>' + el.innerHTML
      if (s.editable) {
        el.querySelector<HTMLSpanElement>('.wj-node-text')?.setAttribute('placeholder', props.editPlaceholder)
        el.innerHTML += '<span class="editable-icon-area">' +
          '<span class="icon node-add" data-cmd="add"></span>' +
          '<span class="icon node-setting" data-cmd="edit"></span>' +
          '<span class="icon node-remove" data-cmd="remove"></span>' +
          '</span>'
      }
      // console.log('formatItem', s, s.editable, el.innerHTML, el.ariaExpanded, el.classList)
    }
    

VmTreeView

script에서는 VmTreeView를 사용한다. wijmo의 TreeView는 계층구조의 데이터를 itemsSource로 설정하면 트리로 표현해 주는 기능만 있다.
VmTreeView는 TreeView를 상속하고, 내부에 CollectionView를 통해서 데이터의 조회, 추가, 수적, 삭제, 저장을 위한 함수가 추가되었다.

Properties

  • collectionView - 트리에 setData로 할당한 원본데이터를 관리하는 데이터셋. VmGrid의 collectionView와 사용법은 동일함.

Method

  • setData - 서버에서 조회한 리스트 형태의 데이터를 입력하면, 트리구조로 변환하고 관리한다.
setData<T extends { [VmTreeView._INDEX]: number }>(listData: T[], option?: { debug: true })

async function query() {
  const { data } = await http.post('/treeMenuReg/query', { corpCd: user.corpCd, userId: user.userId })
  tree.setData(data)
}
  • getData - collectionView의 items를 반환한다.
getData(): any[]
  • getSaveData - 조회한 이후 추가, 수정, 삭제된 데이터를 배열을 반환한다.
getSaveData(): any[]

async function save() {
  const saveData = tree.getSaveData()
  await http.post('/treeMenuReg/save', { flex: saveData })
  query()
}
  • addItem - 선택된 노드 다음에 새로운 아이템을 추가한다.
addItem(addItem: any): void
  • updateItem - 입력한 item의 값을 수정한다. 파라미터의 수정할 데이터는 VmTreeView._INDEX(_index_)를 프로퍼티로 가져야한다.
 updateItem<T extends { [VmTreeView._INDEX]: number }>(this: VmTreeView, treeDataItem: T): void
  • removeItem - 특정 노드 또는 현재 선택된 노드를 삭제한다.
async removeItem(removeNode?: TreeNode): void

Sample

메뉴 트리 샘플.

C:\vmerp\workspace\smart-lite\app\src\views-sample\component\vm-tree-sample\VmTreeSample.vue

<template>
  <VmTree d
    class="folder"
    v-model="selectedNode"
    @initialized="treeInitialized"
    key-id="menuId"
    key-nm="menuNm"
    key-parent="prMenuId"
    key-sort="sortSeq"
    :item-creator="itemCreator"
    :allow-dragging="allowDraggingChecked"
    edit-placeholder="메뉴명을 입력해 주세요." />
</template>

<script setup lang="ts">
import { TreeNode, VmTreeView } from '@/core'
import { TreeNodeDragDropEventArgs, TreeNodeEventArgs } from '@/wijmo/wijmo.nav'

// 트리를 컨트롤할 변수
let tree: VmTreeView

// 트리가 초기화 된 후에 실행할 함수
function treeInitialized(vmTreeView: VmTreeView) {
  // 트리변수애 할당
  tree = vmTreeView

  // 트리가 드래그앤드롭 할때 드롭가능여부 검사가 필요하면 이벤트 추가.
  tree.dragOver.addHandler((s, e) => {
    const evt = e as TreeNodeDragDropEventArgs
    // e.cancel = true //드롭 불가능
  })
}

async function query() {
  const { data } = await http.post('/treeMenuReg/query', { corpCd: user.corpCd, userId: user.userId })
  tree.setData(data)
}

async function save() {
  const saveData = tree.getSaveData()
  await http.post('/treeMenuReg/save', { flex: saveData })
  query()
}

// 트리에 노드 추가할때 제공할 데이터
function itemCreator() {
  const menuId = getNextMenuId()
  return {
    menuId,
    menuNm: '새메뉴' + menuId
  }
}
</script>

Hello