从Apollo.js中的查询中排除店内数据

时间:2017-06-21 12:52:48

标签: reactjs graphql apollo react-apollo

我目前正在一个项目中介绍Apollo,我对缓存/ gql组件组合有一些疑问。

我将使用一个例子来解释:假设我们有一个<Widget>组件&#34; eced&#34;用gql查询定义它的数据要求,这是一个很长的列表。此组件没有<ApolloProvider>,因为它不是独立使用的 - 它必须使用<ApolloProvider>在其他组件中呈现。然后我有两个应用程序,使用此组件:<SimpleApp><ComplexApp>。当<SimpleApp>呈现<Widget>时,后者只是下载数据,一切都很好。但是,<ComplexApp>已经拥有<Widget>使用的部分数据。我希望<Widget>能够解决这个问题并仅下载缺少的数据,而不是下载其查询中定义的整个数据集。这里的业务逻辑将检查Apollo商店中已有的内容,并从<Widget>的查询中删除这些字段。

查询的形式为:

 query WidgetQuery {
   someType {
     id
     a
     b
     c
     d
   }
 }

 query ComplexAppQuery {
   someType {
     b
     c
   }
 }

因此当<Widget>位于<ComplexApp>内时,我不会喜欢下载&#34; a&#34;和&#34; d&#34;,但是否则是。

我有什么方法可以实现这一点,自定义解析器是正确的方法吗?

1 个答案:

答案 0 :(得分:0)

您可以使用@skip@include指令来实现此目标,这些指令基于从其父<Widget><SimpleApp>传递的<ComplexApp>组件的道具零件。让我们调用道具all

<SimpleApp>
  <Widget all={true}/>
</SimpleApp>
<ComplexApp>
  <Widget all={false}>
</ComplexApp>

由于Apollo客户端通常使用id__typename(自动添加到每个查询中)来标识节点,因此您还需要包含id。所以Query看起来像这样:

query widgetQuery($all: Boolean!) {
  someType {
    id
    a @include(if: $all)
    b
    c
    d @include(if: $all)
  }
}
仅当传递的a变量为d时才会包含<{$alltrue

在Apollo中,您可以通过将带有一个参数的函数传递给查询的options来将props传递给变量:

const widgetQuery = gql`
  query widgetQuery($all: Boolean!) {
    someType {
      id
      a @include(if: $all)
      b
      c
      d @include(if: $all)      
    }
  }
`

const WidgetWithQuery = graphql(widgetQuery, {
  options: (ownProps) => ({
    variables: {
      all: ownProps.all
    }
  })
})(Widget)

现在,Apollo客户端确保根据SimpleApp将来自ComplexAppid的所有获得字段合并到一个给定节点。

有关详细信息,请查看this interactive tutorial关于@skip@include