Сучасна диджитал-освіта для дітей — безоплатне заняття в GoITeens ×
Mazda CX 5
×

Хелпер, що конвертує одновимірний масив у дерево коментарів

Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті

Build Status

comments-to-tree — TypeScript / JavaScript хелпер, що конвертує одновимірний масив у дерево коментарів.

Установка:

npm install comments-to-tree --save

Щоб використовувати цей хелпер, коментарі, що приходять з бази даних, повинні мати одне обов’язкове поле commentId та одне опціональне — parentId.

Увесь одновимірний масив з бази даних повинен бути відсортований у зворотному порядку, тобто на початку масива повинні йти найновіші коментарі.

Це мінімальні умови, за яких хелпер вже працюватиме:

import { DefaultCommentsToTree } from 'comments-to-tree';

const commentsTree = DefaultCommentsToTree.getTree(allCommentsFromDb);

Але в реальних умовах, користувачам потрібно буде розширити батьківський клас DefaultCommentsToTree щоб переписати метод transform()

import { DefaultCommentsToTree, DefaultCommentFromDb, DefaultComment } from 'comments-to-tree';


interface CommentFromDb extends DefaultCommentFromDb
{
  // Additional property from database.
  someOtherPropertyFromDb: string;
}

interface Comment extends DefaultComment
{
  // Additional transformed property.
  someOtherProperty: string;
}

class CommentsToTree extends DefaultCommentsToTree
{
  protected static transform(allCommentsFromDb: CommentFromDb[]): Comment[]
  {
    return allCommentsFromDb.map(commentFromDb =>
    {
      return {
        commentId: commentFromDb.commentId,
        parentId: commentFromDb.parentId || 0,
        children: [],
        // Additional property.
        someOtherProperty: commentFromDb.someOtherPropertyFromDb
      };
    });
  }
}

const allCommentsFromDb: CommentFromDb[] =
[
  {commentId: 5, parentId: 2, someOtherPropertyFromDb: 'comment5'},
  {commentId: 4, someOtherPropertyFromDb: 'root comment4'},
  {commentId: 3, parentId: 1, someOtherPropertyFromDb: 'comment3'},
  {commentId: 2, parentId: 1, someOtherPropertyFromDb: 'comment2'},
  {commentId: 1, someOtherPropertyFromDb: 'root comment1'},
];

const commentsTree = CommentsToTree.getTree(allCommentsFromDb);

P.S. не знаю чи відомий спосіб я використовую для побудови дерева, але я його намацав методом тику.

👍ПодобаєтьсяСподобалось0
До обраногоВ обраному0
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Додав приклад використання утиліти написаної на ES5. Тобто в такому разі просто копіюєте код і використовуєте його, не потрібно робити:

npm install comments-to-tree --save

Мммда, я звик використовувати webpack, він вміє завантажувати у браузер модулі у форматі CommonJS, але я не подумав чи це найбільш поширений варіант. Тобто може варто закинути на npmjs comments-to-tree в якомусь іншому форматі, може в UMD...

Как забавно... У меня как раз аналогичная задача и мысли в сторону структуры данных были именно те же самые... :)

Коли я методом тику дійшов до алгоритму перетворення одновимірного масиву у дерево коментарів, я був здивований — на скільки це просто можна зробити, причому без використання рекурсії.

У меня PHP & JS, все будет немножко сложнее (многострочнее)... :)

Тобто ви не хочете щоб клієнт цим займався. Ну не знаю, не знаю... Я ще трохи відрефакторив той шматок коду, що вище показував, тепер він ще лаконічніший.

Чи може ви думаєте, що вам обов’язково треба використовувати TypeScript для цього? — Ні, достатньо буде і JavaScript, щоправда на чистому JavaScript ES5, я сходу так і не скажу як можна розширити клас DefaultCommentsToTree і переписати його метод у дочірньому класі...

Треба буде додати в README приклад коду і для JavaScript, гляну у що транспілюється TypeScript...

Не в этом дело. Часть будет работать на клиенте, но часть работы будет выполняться на сервере. Скорее всего, отдам клиенту все готовое дерево в JSON’е, а браузер пусть его отрисовывает по мере надобности (как потребуется показать), чтобы не перегружать проц и не тормозить реакцию браузера на клиенте. А то заметил я современную тенденцию по максимуму грузить клиента, что приводит к раздражающим задержкам при банальной попытке переключиться между вкладками браузера или опустить страничку в самый низ. :)
Когда я писал первый комментарий, я имел в виду именно представление данных, т.е. хранение в БД и общий принцип работы с табличной формой. С моей точки зрения, это важнее, чем выбранный язык программирования и конкретная реализация алгоритма.

А то заметил я современную тенденцию по максимуму грузить клиента, что приводит к раздражающим задержкам при банальной попытке переключиться между вкладками браузера или опустить страничку в самый низ. :)

Ні, для формування самого дерева JS-об’єктів — такого не буде навіть при тисячах коментарів.

Такий ефект на ДОУ присутній, але, на скільки я розумію, якраз через підготовку рендерінга на бекенді. Ось вам зріз на що витрачається час при завантаженні теми з 800+ коментарями. Тобто, час завантаження сторінки займає біля 10 секунд (на мій десктоп), із них 9 секунд — це очікування відповіді з бекенду, і лише 0.4 секунди — на відпрацювання скрипта.

Впевнений, що такого б не було, якщо б підготовкою коментарів до рендерінгу займався у більшій мірі JavaScript. Припускаю, що час підготовки коментарів до робочого стану запросто зменшився б раза у три, якщо не більше.

Підписатись на коментарі