将Apollo GraphQL updateQuery转换为typePolicy

问题描述

我的头撞在墙上。我已经更新到Apollo 3,并且无法弄清楚如何将typePolicy迁移到fetchMore。我正在执行基于基本连续的分页,这就是我过去合并await fetchMore({ query: MessagesByThreadIDQuery,variables: { threadId: threadId,limit: Configuration.MessagePageSize,continuation: token },updateQuery: (prev,curr) => { // Extract our updated message page. const last = prev.messagesByThreadId.messages ?? [] const next = curr.fetchMoreResult?.messagesByThreadId.messages ?? [] return { messagesByThreadId: { __typename: 'MessagesContinuation',messages: [...last,...next],continuation: curr.fetchMoreResult?.messagesByThreadId.continuation } } } 的结果的方式:

merge

我曾尝试自己写过typePolicy typePolicy,但是它只是不断地加载并引发有关Apollo缓存中重复标识符的错误。这是我的查询 typePolicies: { Query: { fields: { messagesByThreadId: { keyArgs: false,merge: (existing,incoming,args): IMessagesContinuation => { const typedExisting: IMessagesContinuation | undefined = existing const typedIncoming: IMessagesContinuation | undefined = incoming const existingMessages = (typedExisting?.messages ?? []) const incomingMessages = (typedIncoming?.messages ?? []) const result = existing ? { __typename: 'MessageContinuation',messages: [...existingMessages,...incomingMessages],continuation: typedIncoming?.continuation } : incoming return result } } } } } 的样子。

def loss(output):
    # 1 is the imagenet index corresponding to Goldfish,294 to Bear and 413 to Assault Rifle.
    return (output[0][1],output[1][294],output[2][413])

解决方法

因此,我能够解决用例。似乎比实际需要的要困难得多。我本质上必须尝试查找与传入匹配的现有项目并覆盖它们,以及添加缓存中尚不存在的任何新项目。

如果提供了连续令牌,我还必须仅应用此逻辑,因为如果它为null或未定义,我应该只使用传入的值,因为这表明我们正在执行初始加载。

我的文档的形状如下:

{
  "items": [{ id: string,...others }],"continuation": "some_token_value"
}

我创建了一个通用类型策略,可用于所有形状相似的文档。它允许我指定items属性的名称,要缓存的键参数是什么以及graphql类型的名称。

export function ContinuationPolicy(keyArgs: Array<string>,itemPropertyKey: string,typeName: string) {
  return {
    keyArgs,merge(existing: any,incoming: any,args: any) {
      if (!!existing && !!args.args?.continuation) {
        const existingItems = (existing ? existing[itemPropertyKey] : [])
        const incomingItems = (incoming ? incoming[itemPropertyKey] : [])
        let items: Array<any> = [...existingItems]

        for (let i = 0; i < incomingItems.length; i++) {
          const current = incomingItems[i] as any
          const found = items.findIndex(m => m.__ref === current.__ref)

          if (found > -1) {
            items[found] === current
          } else {
            items = [...items,current]
          }
        }

        // This new data is a continuation of the last data.
        return {
          __typename: typeName,[itemPropertyKey]: items,continuation: incoming.continuation
        }
      } else {
        // When we have no existing data in the cache,we'll just use the incoming data.
        return incoming
      }
    }
  }
}