GraphQL 和中继过滤 UI

Posted

技术标签:

【中文标题】GraphQL 和中继过滤 UI【英文标题】:GraphQL & Relay Filtering UI 【发布时间】:2017-04-24 09:35:53 【问题描述】:

提示

如果您要使用中继构建 Google 日历,您将如何构建 GraphQL 架构和中继容器/组件以正确处理显示和隐藏多个日历?

尝试

人们可能会想像这样的架构:

viewer 
  user 
    calendars(calendarIds: [String]) 
      edges,
        node 
          name,
          id,
          events(dates: [Date]) 
            ... edges, node, eventinfo...
          
        
      
    
  

所以,我可以拉下所有日历和所有事件,或者一个特定的日历,或者你有什么。

构建中继容器和组件,我会想象以下内容:

<CalendarView Container>
  <CalendarView>
    <WeekView> or <MonthView> or <Agenda> etc...
      <Event>

这样 CalendarView 中继容器设置请求日历的片段,CalenderView 组件使用setVariables 来切换视图中该日历的显示/隐藏。

我遇到的问题(这让我头晕目眩)是Day/Week/Month/Agenda 组件是组合视图——也就是说,它们需要来自所有选定的事件。

情节变厚

现在,听起来不错 - 让 CalendarView 设置 calendarId 变量并将结果事件向下传递,对吗?嗯……有点。现在CalendarView 的片段由一组calendarIds 构成,因此打开或关闭一个calendar 会更改要获取的整个树。

有什么问题吗?

据我所知,relay 将calendarIds 的每个组合视为完全不同的提取。所以,当我打开一个新的id 时,它会获取所有事件,即使是我已经获取的那些日历。

按代码放置:

fragment calendar(calendarIds: [1, 2])  ...  

是一个完全不同的获取方式:

fragment calendar(calendarIds: [1, 2, 3])  ... 

这……糟糕。这些日历上可能有很多事件,而过度获取是一个杀手。

理论上,我可以为每个日历创建一个容器,但是我如何将这些日历上的事件组合起来,并将它们传送到一个公共子组件中呢?日历不能分层,因为事件需要移动以响应其他事件,即使是单独日历上的事件(左/右移动以并排显示)。

想法?我的脑袋好痛。

【问题讨论】:

【参考方案1】:

在代码方面,calendar(calendarIds: [1, 2]) 是与 calendar(calendarIds: [1, 2, 3]) 完全不同的查询

是的。 GraphQL 不为字段参数分配语义,因此 Relay(或任何其他 GraphQL 客户端)不知道 calendarIds 参数对应于结果的 id。不过,这是一个足够常见的用例,Relay 支持一个特殊的 nodes(ids: [ID!]) 根字段(在 Query 类型上),该字段被视为您所期望的。要使用它,请在您的架构中实现一个 nodes 字段,该字段以数组的形式返回结果,其顺序与输入 ID 的顺序匹配,对于任何无法加载的结果,都包含空条目。例如。如果输入 ID 是 [1,2,3],您将返回 [result1, result2, result3]。使用此字段时,Relay 将根据先前获取的数据区分参数参数(因为它假设此特定字段的参数具有 ids 的语义含义)。

【讨论】:

nodes 根字段上是否有文档?我们通过graphql-relay 实现了一个根节点字段,但我在nodes 上找不到任何东西。 另外,“复数标识根字段”是否类似于上述方法?在我看来,就像“复数标识根字段”一样,使用 nodes 字段需要与 id 进行一对一映射的对象。理想情况下,我可以使用变量查询一大组对象(事件),这些对象(事件)没有按输入 id 很好地分组(输入:[3 个 id 数组],输出:[n 个事件数组]),但是这两种方法似乎都需要创建一些中间对象(输入:[Array of 3 ids],输出:[Array of 3 objects that have events])。 nodes 字段没有记录,但它的工作原理与我上面描述的一样。不需要中间结果对象,即您可以执行 node(ids: [array of 3 event ids]) 并返回 [array of 3 events] - 事件结果只需与 args 的顺序相同。 感谢您的讨论——这非常有帮助。我想我可以重构一些东西来为给定的 calendarId 请求 eventIds,然后按事件 id 请求事件,但理想的情况是为给定的日历请求一堆事件。在这种情况下,calendarId 和 event 之间没有一对一的映射。

以上是关于GraphQL 和中继过滤 UI的主要内容,如果未能解决你的问题,请参考以下文章

我对中继和graphql解析方法感到困惑

中继编译器无法在 Typescript 中提取和使用 graphql 查询

如何使用带有 Typescript 的泛型将中继(graphql)连接映射到边缘节点

如何在现有 GraphQL 服务器上添加根和查看器查询以支持中继

中继棱镜 graphql 更新存储

无法创建中继容器; graphql.js 文件似乎有 webpack 工件?