使用 writeFragment 更新属于对象的字段?

Using writeFragment to Update a Field Belonging to an Object?

我正在尝试让我的第一个 writeFragment 工作。

物体形状如下:

resolutions {
  _id
  name
  completed
  goals {
    _id
    name
    completed
  }
}

我刚刚 运行 成功添加新 goal 的客户端上的变更,现在我正在尝试让客户端页面自动更新并显示新目标那是刚刚添加的。

我已经 readFragment 工作了。它成功地读入了决议。我读的是Resolution,而不是goals,因为作为resolution的一个字段,goals没有自己的id。

这是我的 update 函数,显示 readFragmentwriteFragment:

<Mutation
  mutation={CREATE_GOAL}
  update={(cache, { data: { createGoal } }) => {
    let resId = 'Resolution:' + resolutionId;

    const theRes = cache.readFragment({
      id: resId,
      fragment: GET_FRAGMENT_GOAL,
    });

    theRes.goals = theRes.goals.concat([createGoal]); //<== THIS WORKS

    cache.writeFragment({
      id: resId,
      fragment: SET_FRAGMENT_GOAL,
      data: { __typename: 'Resolution', goals: theRes.goals },
      });
    }}
>

...这是片段的 gql:

   const GET_FRAGMENT_GOAL = gql`
    fragment targetRes on resolutions {
      name
      completed
      goals {
        _id
        name
        completed
      }
    }
  `;


  const SET_FRAGMENT_GOAL = gql`
    fragment targetGoal on resolutions {
      __typename
      goals
    }
  `;

这是我收到的控制台错误:

You are using the simple (heuristic) fragment matcher, but your queries contain union or interface types.

Apollo Client will not be able to able to accurately map fragments.To make this error go away, use the IntrospectionFragmentMatcher as described in the docs: http://dev.apollodata.com/react/initialization.html#fragment-matcher

我阅读了 IntrospectionFragmentMatcher,它看起来对我的情况来说太过分了。看来我做错了什么。这是我同时遇到的另一个错误:

Uncaught (in promise) TypeError: Cannot read property 'data' of undefined

我对 writeFragment 的调用有什么问题?

经过几个小时的学习,我学到了很多关于片段的知识!

我成功了。以下是更新后的片段和查询定义:

import gql from "graphql-tag";

let resolutionQueryFragments = {
    goalParts: gql`
    fragment goalParts on Goal {
        _id
        name
        completed
    }
  `,
};


resolutionQueryFragments.resolutionGoals = gql`
    fragment resolutionGoals on Resolution {
        goals{
            _id
            name
            completed   
        }
    }
`;

const GET_RESOLUTIONS = gql`
  query Resolutions {
    resolutions {
      _id
      name
      completed
      ...resolutionGoals
    }
     user {
      _id
    }
  }
  ${resolutionQueryFragments.resolutionGoals}
`;

const CREATE_RESOLUTION = gql`
    mutation createResolution($name: String!) {
      createResolution(name: $name) {
        __typename
        _id
        name
        ...resolutionGoals
        completed
      }
    }
    ${resolutionQueryFragments.resolutionGoals}
`;

const GET_RESOLUTIONS_FOR_MUTATION_COMPONENT = gql`
  query Resolutions {
    resolutions {
      _id
      name
      completed
      ...resolutionGoals
    }
  }
     ${resolutionQueryFragments.resolutionGoals}
`;

const CREATE_GOAL = gql`
  mutation createGoal($name: String!, $resolutionId: String!) {
    createGoal(name: $name, resolutionId: $resolutionId) {
        ...goalParts
      }
  }
     ${resolutionQueryFragments.goalParts}
`;

export {resolutionQueryFragments, GET_RESOLUTIONS, GET_RESOLUTIONS_FOR_MUTATION_COMPONENT, CREATE_RESOLUTION, CREATE_GOAL}

...这是更新后的 Mutation 组件:

import React, {Component} from "react";
import gql from "graphql-tag";
import {graphql} from "react-apollo";
import {Mutation} from "react-apollo";
import {withApollo} from "react-apollo";
import {resolutionQueryFragments, CREATE_GOAL} from '../../imports/api/resolutions/queries';

const GoalForm = ({resolutionId, client}) => {
    let input;

    return (
        <Mutation
            mutation={CREATE_GOAL}
            update={(cache, {data: {createGoal}}) => {
                let resId = 'Resolution:' + resolutionId;
                let currentRes = cache.data.data[resId];
                let theGoals = cache.readFragment({
                    id: resId,
                    fragment: resolutionQueryFragments.resolutionGoals
                });
                theGoals = theGoals.goals.concat([createGoal]);
                cache.writeFragment({
                    id: resId,
                    fragment: resolutionQueryFragments.resolutionGoals,
                    data: {goals: theGoals}
                });
            }}
        >
            {(createGoal, {data}) => (
                <div>
                    <form
                        onSubmit={e => {
                            e.preventDefault();
                            createGoal({
                                variables: {
                                    name: input.value,
                                    resolutionId: resolutionId
                                }
                            });
                            input.value = "";
                        }}
                    >
                        <input
                            ref={node => {
                                input = node;
                            }}
                        />
                        <button type="submit">Submit</button>
                    </form>
                </div>
            )}
        </Mutation>
    )
        ;
};

export default withApollo(GoalForm);