Hiển thị view tree trên HTML bằng Java

java

(84.quangphuc) #1

Database bảng Persion

STT name parent level
1 A 1
2 B 1
3 A1 A 2
4 A11 A1 3
5 A12 A1 3
6 A121 A12 4

Em có một bảng Persion có các thuộc tính như trên ,Sử dụng vòng lặp, code Java như thế nào để lấy dữ liệu từ database và hiển thị được theo đúng cấu trúc như đoạn HTML trên, em xin cảm ơn

tree


(Giang Phan) #2

Bạn có thể sử dụng đệ quy để lấy. Đầu tiên lấy danh sách Person có parent là rỗng, danh sách này gọi là root. Sau khi có danh sách root, bạn loop qua danh sách này và lấy danh sách có cha là root[i].parent, tiếp tục lặp qua danh sách con có được để lấy danh sách con cấp 2 theo parent, cứ như thế bạn sẽ có được tất cả dữ liệu phân cấp.
Lớp Person của bạn bao gồm các thuộc tính: name, parent, List chidrens.
Quan trọng là có thêm thuộc tính childrens, để lưu giữ danh sách con của nó.


(84.quangphuc) #3

Mình đang gặp khó khăn trong lấy số lượng vòng lặp, bạn có thể giúp mình được không


(Hung) #4

Có 2 bước:

  • Tạo tree từ bảng Person
  • Tạo HTML bằng cách duyệt tree.

Bước tạo tree:

  • Tạo root node gồm name và mảng children
  • Duyệt từng hàng trong table Person
    • Tìm kiếm (search) row.parent trong tree
    • Nếu tìm thấy, insert node đó vào tree

Bước tạo HTML:

  • Duyệt theo Preorder traversal
  • Chú ý các điều kiện: node có name không? node có subtree không?

JavaScript
function buildTree(rows) {
  let root = {
    level: 0,
    children: []
  };

  function searchTree(name) {
    function _searchTree(node, name) {
      if (node.name == name) {
        return node;
      }
      for (let child of node.children) {
        let res = _searchTree(child, name);
        if (res) return res;
      }
    }
    return _searchTree(root, name);
  }

  for (let row of rows) {
    if (row.level == 1) {
      root.children.push({
        name: row.name,
        level: 1,
        children: []
      });
      continue;
    }
    let node = searchTree(row.parent);
    if (node) {
      node.children.push({
        name: row.name, 
        level: node.level + 1,
        children: []
      });
    }
  }

  return root;
}

function renderHTML(node) {
  function renderChildren() {
    return node.children
      .map(child => renderHTML(child))
      .join('');
  }

  if (node.name) {
    if (node.children.length > 0) {
      return `<li>${node.name}<ul>${renderChildren()}</ul></li>`;
    }
    return `<li>${node.name}</li>`;
  } else {
    if (node.children.length > 0) {
      return `<ul>${renderChildren()}</ul>`;
    }
    return '';
  }
}

let html = renderHTML(
  buildTree([
    { name: 'A', level: 1 },
    { name: 'B', level: 1 },
    { name: 'A1', parent: 'A', level: 2 },
    { name: 'A11', parent: 'A1', level: 3 },
    { name: 'A12', parent: 'A1', level: 3 },
    { name: 'A121', parent: 'A12', level: 4 }
  ])
);
console.log(html);

Note: Java dài + khai báo custom class nữa => chuyển sang JavaScript cho đỡ.


(84.quangphuc) #5

Mình lấy được danh sách root có parent là rỗng rồi khi mình loop danh sách cha thì là rỗng mà bạn


(Giang Phan) #6

Ý tưởng như trên, bạn xem code bên dưới rồi implement thêm cho phù hợp:

class Person { id, parentId, List<Person> childrens };

List<Person> persons = get(null);
for (Person p : people) {
	setChildrens(p);
}

private void setChildrens(Person parent) {
	List persons =  getPersons(parent.ParentId);
	if (persons.isNotEmpty()) {
		parent.setChildrens(persons);
		for (Person child : persons) {
			setChildrens(child);
		}
	}
}

private List<Person> getPersons(parentId) { 
	// select * from person where parent = :parentId;
}

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?