关于列表数据删除时前端展示那些事 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
请不要在回答技术问题时复制粘贴 AI 生成的内容
iam

关于列表数据删除时前端展示那些事

  •  2
     
  •   iam Sep 16, 2022 2627 views
    This topic created in 1319 days ago, the information mentioned may be changed or developed.

    今天下午,办公室的民工都在热火朝天的堆代码。突然前端的同志说,删除列表中的一些数据时会造成数据丢失或者重复,我有没有什么看法。作为一个资深不务正业的后端,我决定加入了这场讨论。

    交代一下背景:用户个人中心的任务列表需要做批量删除,因为做了分页,根据 limit (page - 1) * page_size, page_size 确实会出现这样的问题。

    数据举例: page1:00 01 02 03 04 05 06 07 08 09 page2:10 11 12 13 14 15 16 17 18 19 page320 21 22 23 24 25 26 27 28 29 page4:30 31 32 33 34 35 36 37 38 39 page5:40 41 42 43 44 45 46 47 48 49 

    基于这样的背景我们 3 个人(分别称 A 、C 、D (本人),因为感觉小 B 不是很礼貌)提出了几种解决方案:

    1 )做标记

    C:或许把删除先做成标记,等到用户退出列表页或者回到个人中心的时候再提交删除.
    A & D:这样好像不太稳定,如果用户非正常退出的话不是很好正常提交,造成数据删除失败的现象,而且如果删除失败也不是很好的反馈给用户

    总结:NO

    2 )删除部分

    D:把删除数据最上页的数据更新,下面的全删除掉呢 例:删除 11 22 23 30 这些数据的话,就重新加载 page2 ,page3 、4 、5 全都删掉。数据变为

    page1:00 01 02 03 04 05 06 07 08 09 page2:10 12 13 14 15 16 17 18 19 20 

    A & C:这样用户体检不是很好,最好能定位到用户访问数据的最后一项

    总结:不适合批量删除,但是单项删除的话好像是可以的,因为删除页就是所在页?

    3 )补齐方式

    D:那删除之后,把最后一页做成补齐页记录误差,重新请求最后一页,创建一个新的页放进去呢 例:删除 11 22 23 30 这些数据的话,就把 page5 的前 4 个保留,删除掉后面 6 个,然后重新请求 page5 ,保存在 page6 ,记录误差为 1 ,数据变为

    page1:00 01 02 03 04 05 06 07 08 09 page2:10 12 13 14 15 16 17 18 19 page3:20 21 24 25 26 27 28 29 page4: 31 32 33 34 35 36 37 38 39 page5:40 41 42 43 page6: 44 45 46 47 48 49 50 51 52 53 

    此时的 page6 的数据为 page5 的数据,page1 + ... + page5 是前 4 页的总和,误差记录为 1 ,请求时页码加上误差即可
    A & C:这样会有点问题,如果删除的数据包括 page5 中的数据,那么补齐的数据需要去掉这些数据,如果删除的数据超过了一页,就需要计算最后几页,会比较麻烦

    总结:可以实现,但是较复杂

    4 )重新整合

    A:基于 3 的方法,在删除完成后把页码重新整合,再请求最后一页的数据,数据变为

    page1:00 01 02 03 04 05 06 07 08 09 page2:10 12 13 14 15 16 17 18 19 20 page3: 21 24 25 26 27 28 29 31 32 33 page4: 34 35 36 37 38 39 40 41 42 43 page5: 44 45 46 47 48 49 50 51 52 53 

    总结:可以实现,但是数据量较大时可能会渲染卡顿?

    5 )请求时添加偏移量

    C:可以请求的时候,加上 delete____count ,数据查询时变为 limit (page - 1) * page_size - delete_count, page_size

    总结:可以实现,需要前后端的代码都做一下改动,可能因为数据源的程序不太好改动,那边的同事说实现不了 - -#

    写在后面

    1.以上讨论都是建立用户操作自己的列表时所做的操作,而且没有考虑到多端登录的问题; 2.如果是在后台管理删除掉数据的话,用户的列表也会出问题,可能需要做缓存或者用别的方式通知用户? 3.想起之前做的竞价功能,需要最新的出价在上面,然后做分页,列表的数据也会用这种问题,如果加上请求时间就可以解决,如果有需要的同志可以这样实现。 好像还有很多的问题没有解决,但是今天有点晚了,就先这样。 第一次写这种主题,抛砖引玉,如果大家有什么好的解决方法欢迎一起讨论哈 
    14 replies    2022-09-16 09:58:02 +08:00
    baiyun
        1
    baiyun  
       Sep 16, 2022 via iPhone
    为什么删除数据会造成丢失或者重复显示?
    baiyun
        2
    baiyun  
       Sep 16, 2022 via iPhone
    参考 ProTable 。前端处理基本都是固定的两种模式
    renmu
        3
    renmu  
       Sep 16, 2022 via Android
    按我的理解是 你们页面是无限滚动,然后删除之后导致分页出现问题了
    akira
        4
    akira  
       Sep 16, 2022
    参考 gmail 批量删除时候的实现方案。要么就是基于当前页的手动选择,要么就是基于规则的选择,且规则选择会有上限。
    edis0n0
        5
    edis0n0  
       Sep 16, 2022
    我们这边的处理方案是任何场景下删除都只是隐藏,API 会返回已经删除的数据只是前端不显示给用户,然后弄个计划任务每天凌晨 4 点彻底删除 200 天前标记删除的内容。
    Pastsong
        6
    Pastsong  
       Sep 16, 2022
    不要传 page ,传 offset
    CEBBCAT
        7
    CEBBCAT  
       Sep 16, 2022
    需要清晰阐述一下业务模型。为什么会数据丢失或重复?每个条目的排序 ID 是不是都是单调递增的?

    我猜楼主是瀑布流式列表?感觉产品太菜或者弱势。这种情况应该先决定能够接受的交互模型再设计实现方案。假如批量删除的条目直接抽空的话,页面会大幅度变化,用户还能记得刚才看到哪里吗?
    Building
        8
    Building  
       Sep 16, 2022 via iPhone
    前端数据和后端数据为什么非要耦合在一起? 前端取数据的时候应该用 cursor + offset
    iam
        9
    iam  
    OP
       Sep 16, 2022
    统一回复一下对 “删除数据会造成丢失或者重复显示” 的疑问,哈哈,可能描述的不是很清晰。
    前端请求数据的时候会传 page 和 page_size ,然后后端根据这个去查询。
    SQL:select *** from *** where *** limit (page - 1) * page_size, page_size;

    假如还是这些数据的话,在 page1 删除 00 ,那么前两页的数据就会变成
    page1:01 02 03 04 05 06 07 08 09 10
    page2:11 12 13 14 15 16 17 18 19 20

    原 page1:00 01 02 03 04 05 06 07 08 09

    因为已经渲染过,不做处理的话,就会造成 10 这条数据丢失。
    如果是用户删除的,大家说的这些方式好像都可以解决,但是后台删除数据的话,还是会有这样的问题。
    昨晚躺在床上想:在查询数据的时候需要传参开始访问时间,在这个时间之后删除的数据统计一下做一个偏移。
    例:
    load_start_time = 2022 09 16 00:00:00;(请求参数)
    delete_count = select count(***) from *** where delete_time > load_start_time
    不管是 offset 还是 page * page_szie , 游标都要向左偏移这个时间之后删除的数据条数 offset - delete_count
    xuanbg
        10
    xuanbg  
       Sep 16, 2022
    无限滚动的数据按时间倒序分页的话,确实存在一个几乎无法解决的问题。就是数据发生变化后加载下一页数据,要么重复(添加数据,把最后一条数据挤到下一页了),要么丢数据(删除数据,下一条数据顶到上一页去了)。传 offset 也仅仅能解决只有一个用户在操作的情况,别人给你干掉一条数据,你的 offset 是不会变的。
    唯一有效的办法是传当前页的最后一条数据的 id ,这要求 id 是自增或雪花 id 这种单调增长的。别无他法。
    Moeyua
        11
    Moeyua  
       Sep 16, 2022
    在页面加载时前端就「一次性」把数据全部获取下来,这里的「一次性」并不一定是一次请求,可以是多次请求,但重点是你要在用户删除数据前「主动」把所有数据加载完毕。之后前端自己做分页。
    这种方法的缺陷就是不适用于非常大的数据量,而且无法感知到后台删除的数据。但话又说回来,如果后台删了一条用户已经渲染过的数据,这种情况真的是无解,处理起来相当复杂。
    Moeyua
        12
    Moeyua  
       Sep 16, 2022
    正好之前处理类似问题时候画过一个图,给不清楚的人解释下为什么会丢数据
    zhyl
        13
    zhyl  
       Sep 16, 2022
    介绍一下我的做法:前端表格列表同时只显示一页的数据,触发删除行为时,先在后端删除,然后前端手动移除这一项,如果这一页的数据都被移除了,重新请求接口拉取新的数据
    zhyl
        14
    zhyl  
       Sep 16, 2022
    @zhyl 总结就是尽量少的在删除时重新请求后端拉取数据
    About     Help     Advertise     Blog     API     FAQ     Solana     3325 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 55ms UTC 13:14 PVG 21:14 LAX 06:14 JFK 09:14
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86