简体   繁体   English

GraphQL和中继过滤UI

[英]GraphQL & Relay Filtering UI

THE PROMPT 提示

If you were to build Google Calendar using relay, how would you structure the GraphQL schema and the Relay containers/components to properly handle showing & hiding multiple calendars? 如果您使用中继构建Google日历,您将如何构建GraphQL架构和中继容器/组件以正确处理显示和隐藏多个日历?

THE ATTEMPT 试图

One might imagine a schema like this: 有人可能会想到这样的架构:

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

So, I can pull down all the calendars and all the events, or a specific calendar, or what have you. 所以,我可以下载所有日历和所有活动,或特定日历,或者你有什么。

Structuring the Relay Containers and components, I would imagine the following: 构建中继容器和组件,我想象如下:

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

Such that the CalendarView relay container sets up the fragment requesting the calendars, and the CalenderView component uses setVariables to toggle the showing/hiding of that calendar in the view. 这样CalendarView中继容器设置请求日历的片段,而CalenderView组件使用setVariables来切换视图中该日历的显示/隐藏。

The problem that I'm encountering (and that's making my head spin) is that the Day / Week / Month / Agenda components are combinatorial views — that is, they require the data from all selected events. 我遇到的问题(这让我头晕目眩)是Day / Week / Month / Agenda组件是组合视图 - 也就是说,它们需要来自所有选定事件的数据。

THE PLOT THICKENS 地图厚度

Now, that sounds just fine — have the CalendarView set the calendarId variables and pass the resulting events down, right? 现在,这听起来很好 - 让CalendarView设置calendarId变量并将结果事件传递下来,对吧? Well... kind of. 嗯...有点儿。 Now the fragment for CalendarView is constructed with a set of calendarIds , such that toggling one calendar on or off changes the entire tree of what is to be fetched. 现在, CalendarView的片段由一组calendarIds ,因此打开或关闭一个calendar更改要获取的整个树。

THE GOTCHA? GOTCHA?

As far as I can tell, relay sees each combination of calendarIds as an entirely different fetch. 据我所知,relay将calendarIds每个组合视为完全不同的提取。 So, when I toggle on a new id it fetches all the events, even for those calendars I've already fetched. 因此,当我切换一个新的id它会获取所有事件,即使对于我已经提取的那些日历也是如此。

Put code-wise: 放入代码:

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

Is an entirely different fetch from: 完全不同的取得:

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

This is ... bad. 这是不好的。 There can be a lot of events on those calendars and the over-fetching is a killer. 这些日历上可能会有很多事件,并且过度获取是一个杀手。

In theory, I could create a container per calendar, but then how would I combine the events on those calendars and pipe them into a common sub-component? 从理论上讲,我可以为每个日历创建一个容器,但是如何将这些日历上的事件组合在一起并将它们组合成一个公共子组件? The calendars can't be layered because events need to move around in reaction to other events, even those on separate calendars (shifting left/right to show them side-by-side). 日历无法分层,因为事件需要四处移动以响应其他事件,即使是在不同日历上的事件(向左/向右移动以并排显示它们)。

Thoughts? 思考? My brain hurts. 我的脑袋疼。

Put code-wise, calendar(calendarIds: [1, 2]) is an entirely different query from calendar(calendarIds: [1, 2, 3]) 放置代码, calendar(calendarIds: [1, 2])是一个完全不同的calendar(calendarIds: [1, 2, 3])查询calendar(calendarIds: [1, 2, 3])

Yup. 对。 GraphQL doesn't assign semantics to field arguments, so Relay (nor any other GraphQL client) doesn't know that the calendarIds arguments correspond to the ids of the results. GraphQL没有为字段参数赋予语义,因此Relay(也没有任何其他GraphQL客户端)不知道calendarIds参数对应于结果的id。 This is a common enough use-case, though, that Relay supports a special nodes(ids: [ID!]) root field (on the Query type) that is treated as you were expecting. 但是,这是一个常见的用例,即Relay支持特殊nodes(ids: [ID!])根域(在Query类型上),它们按照您的预期处理。 To use it, implement a nodes field in your schema that returns results as an array whose order matches that of the input ids, with null entries for any results that couldn't be loaded. 要使用它,请在模式中实现一个nodes字段,该字段将结果作为一个数组返回,该数组的顺序与输入ID的顺序相匹配,对于任何无法加载的结果都使用null条目。 Eg if the input ids are [1,2,3] , you'd return [result1, result2, result3] . 例如,如果输入id为[1,2,3] ,则返回[result1, result2, result3] When using this field, Relay will diff arguments arguments against previously fetched data (because it makes the assumption that the arguments of this particular field have a semantic meaning as ids). 使用此字段时,Relay将针对先前获取的数据区分参数参数(因为它假设此特定字段的参数具有ids的语义含义)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM