写了一个 [排序只需要修改一个对象数据] 的模式

查看 25|回复 0
作者:rizon   
废话:
最近在对 notelive.cc 这个网站做一个新版本(不会替代这个网站,只是做一个新项目),然后遇到了目录树的排序老问题。
正题:
出于降低数据库写压力,简化初始化数据结构,以及我就是不喜欢排序要修改两个对象的个人原因等,因此做了这个排序模型。
实现效果:
[ol]
  • 数据结构初始化不需要包含排序信息(个人业务需要,默认按照时间排序,本 demo 里按照 id 排序)
  • 排序时只需要修改拖动的对象的数据,不需要操作目标位置的对象。
    [/ol]
    有什么好的优化建议,也欢迎贴出来。

    "use client";
    import { useRef, useState } from "react";
    interface Item {
      id: number;
      orderTime: number | undefined;
      pre: number | null | undefined;
    }
    let init: Item[] = [
      {
        id: 1,
        orderTime: undefined,
        pre: undefined,
      },
      {
        id: 4,
        orderTime: undefined,
        pre: undefined,
      },
      {
        id: 2,
        orderTime: undefined,
        pre: 3,
      },
      {
        id: 3,
        orderTime: undefined,
        pre: undefined,
      },
    ];
    export default function SortPage() {
      const source = useRef(null);
      const target = useRef(null);
      const [list, setList] = useState[I](init);
      const doSort = () => {
        if (!source.current || !source.current.value) {
          setList(reSort(list));
          return;
        }
        const sourceItem = list.find(
          (item) => item.id == parseInt(source.current!.value)
        );
        if (!sourceItem) {
          alert("not fount sourceItem");
          return;
        }
        const targetItem = target.current!.value
          ? list.find((item) => item.id == parseInt(target.current!.value))
          : null;
        // 只需要修改 sourceItem 的值,不用处理 targetItem
        if (!targetItem) {
          sourceItem.orderTime = Date.now();
          sourceItem.pre = -1;
        } else {
          sourceItem.orderTime = Date.now();
          sourceItem.pre = targetItem.id;
        }
        setList(reSort(list));
      };
      return (
       
          
            
              移动的元素:
            
            
              目标元素的后面(留空首位):{" "}
             
            
            
             
                移动
             

            
          
          
            {list.map((item) => {
              return (
                
                  id: {item.id}
                  orderTime: {item.orderTime}
                  pre: {item.pre}
                
              );
            })}
          
       
      );
    }
    function reSort(originList: Item[]) {
      const list = [...originList];
      const sortById = (pre: Item, next: Item) => {
        // id 从小到大排序
        if (pre.id > next.id) {
          return 1;
        } else if (pre.id  {
        let preOrderTime = pre.orderTime || 0;
        let nextOrderTime = next.orderTime || 0;
        // orderTime 从小到大排序
        if (preOrderTime > nextOrderTime) {
          return 1;
        } else if (preOrderTime  e.id === sourceId);
        if (sourceIdx === -1) {
          return;
        }
        const sourceItem = array[sourceIdx];
        const indexToInsert = list.findIndex((e) => e.id === targetItemId);
        array.splice(sourceIdx, 1);
        if (indexToInsert > -1) {
          array.splice(indexToInsert + 1, 0, sourceItem); // 在目标元素后面插入
        } else {
          array.unshift(sourceItem); // 如果找不到元素 b ,则将元素 a 放在数组首位
        }
      }
      return list;
    }
    文末:
    如果大家对 notelive.cc 这个网站有什么建议,或对正在内测的新笔记产品有兴趣,或单纯想要唠唠嗑,可以加微信群哈。
  • 您需要登录后才可以回帖 登录 | 立即注册