应该如何对列表中的项目进行重新排序,并更新多个对象,如何使用 GraphQL 突变进行持久化?

Posted

技术标签:

【中文标题】应该如何对列表中的项目进行重新排序,并更新多个对象,如何使用 GraphQL 突变进行持久化?【英文标题】:How should reordering items in a list, and updating multiple objects, be persisted with GraphQL mutations? 【发布时间】:2017-08-31 00:49:04 【问题描述】:

我正在使用的堆栈

Scaphold.io 作为我的 GraphQL 服务器 Vue Apollo 在客户端 Vue Draggable 处理拖放的库

我想要做什么

我正在构建一个向用户显示多个列表的应用,每个列表都包含多张卡片。在列表中,卡可以由用户重新排序。卡片也可以从一个列表移动到另一个列表,这会改变卡片的父列表,以及卡片在源列表和目标列表中的顺序。

这是一个 GIF,显示了我的应用中卡片/列表和重新排序的 UI。您在这里看到的一切都发生在客户端,并且更改不会持久保存到数据库中:

这是我用来构建 UI 的查询:

const foo = gql`
  query foo 
    getAccount(id: "xxxxx") 
      cardLists         
        edges 
          node 
            id
            name
            cards(orderBy: field: order, direction: ASC) 
              edges 
                node 
                  id
                  name
                  order
                
              
            
          
        
      
    
  
`

这是来自 Vue Draggable 项目的 GIF,进一步说明了我在做什么(注意数据中的“订单”值):


问题

我不知道如何构建一个突变来处理重新排序,以便正确保留移动的卡片以及对源列表和目标列表排序的更改。

在 Scaphold 中构建模式意味着我需要(我认为)使用它提供的突变。我看不到将多张卡片和列表传递给单个突变的方法,以便我可以一次更新所有内容。

这是 Scaphold.io 中示例项目的端点:https://us-west-2.api.scaphold.io/graphql/soreorderingexample

这是由 Scaphold.io 生成的架构:https://d3uepj124s5rcx.cloudfront.net/items/1e1m2q3F170C2G3M0v2p/schema.json


我的问题

在 GraphQL 中如何正确看待此类持久更改? 鉴于 Scaphold 的限制和自以为是的行为,我应该如何进行突变?

【问题讨论】:

【参考方案1】:

我不了解 Scaphold,但您可以将所有项目保存在一个数组中,并始终在一个突变中更新,或者您可以逐个更新列表项。

进行解耦手动排序的最简单方法是设置一个order: Float 字段,每次您想在其他两张卡片之间移动一张卡片时将其设置为(prev.order + next.order)/2,或1 多于/少于如果您移到后/前,则为最后一个/第一个。

鉴于浮点精度,您可以在精度受损之前在相同的两张卡片之间执行 53 次此操作,此时您可以重新分配 order 字段或手动将有问题的卡片向上移动然后再向下移动。

【讨论】:

“但是您可以将所有项目保存在一个数组中,并且始终在一个突变中更新,或者您可以一个一个地更新列表项目。” — 谢谢。抱歉新手问题,但是这样的查询是什么样的? 感谢 w00t,不幸的是,我似乎无法配置 Scaphold 突变以接受卡片输入列表。

以上是关于应该如何对列表中的项目进行重新排序,并更新多个对象,如何使用 GraphQL 突变进行持久化?的主要内容,如果未能解决你的问题,请参考以下文章

如何允许用户重新排序列表中的项目?

如何在 jQuery UI 中将多个可排序列表相互连接?

重新排序有序列表

如何允许对不在编辑模式下的 SwiftUI 列表中的行进行重新排序?

Hashtable一个键多个值 在遍历怎么做啊

Android-java-如何按对象内的某个值对对象列表进行排序