angular - 带有插值的 graphql-codegen 动态场

标签 angular typescript graphql graphql-tag graphql-codegen

我正在使用 graphql-codegen从 graphql 模式生成 typescript 类型。我正在尝试创建一个带有动态字段的片段。

schema.ts

这是graphql-codegen生成的类型。

/** User Type */
export type UserType = {
  __typename?: 'UserType';
  id: Scalars['ID'];
  avatar: Scalars['String'];
  email: Scalars['String'];
  name: Scalars['String'];
  showPostsInFeed: Scalars['Boolean'];
  username: Scalars['String'];
};

user.model.ts

我在整个应用程序中使用这些接口(interface)来进行验证和一致性。

export interface IUserBase {
  id: string;
  avatar: string;
  name: string;
  username: string;
}

export interface IUserPost extends IUserBase {
  showPostsInFeed: boolean;
}

export interface IUserProfile extends IUserBase, IUserPost {
  email: string;
}

show.ts

这是用于生成的文件。在这里,我想使用我现有的 IUserPostIUserProfile 接口(interface)制作一个带有动态字段的片段,以便重用这些字段并避免在片段中一个一个地重复它们。

import gql from 'graphql-tag';
import { keys } from 'ts-transformer-keys';

import { IUserProfile, IUserPost } from '../../user.model';

const keysUserPofile = keys<IUserProfile>();  //Get all interface keys
const keysUserPost = keys<IUserPost>();  //Get all interface keys

//Fragments
export const fragments = {
  userProfile: gql`
    fragment UserProfile on UserType {
      ${keysUserPofile.join('\n')}    //Interpolation
    }
  `,
  userPost: gql`
    fragment UserPost on UserType {
      ${keysUserPost.join('\n')}    //Interpolation
    }
  `
};

//Queries
export const userProfileQuery = gql`
    query UserProfileQuery($id: String!) {
      showUser(id: $id) {
        ...UserProfile
      }
    }
`;

export const userPostQuery = gql`
    query UserPostQuery($id: String!) {
      showUser(id: $id) {
        ...UserPost
      }
    }
`;

当我尝试使用插值传递这些字段时,出现此错误:

$ npm run generate

> gogofans-ui@0.0.0 generate C:\Development\GogoFans\gogofans-ui
> graphql-codegen --config codegen.yml

  √ Parse configuration
  > Generate outputs
    > Generate src/app/core/graphql/schema.ts
      √ Load GraphQL schemas
      × Load GraphQL documents
        → Syntax Error: Expected Name, found "}".
        Generate

Found 1 error

× C:/Development/GogoFans/gogofans-ui/src/app/users/graphql/fragments/show.ts
GraphQLError: Syntax Error: Expected Name, found "}".

at syntaxError (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\error\syntaxError.js:15:10)
at Parser.expectToken (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:1423:40)
at Parser.parseName (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:92:22)
at Parser.parseField (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:289:28)
at Parser.parseSelection (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:278:81)
at Parser.many (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:1537:26)
at Parser.parseSelectionSet (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:265:24)
at Parser.parseFragmentDefinition (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:410:26)
at Parser.parseDefinition (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:134:23)
at Parser.many (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:1537:26)
at Parser.parseDocument (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:109:25)
at Object.parse (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:36:17)
at Object.parseGraphQLSDL (C:\Development\GogoFans\gogofans-ui\node_modules@graphql-tools\utils\index.cjs.js:601:28)
at parseSDL (C:\Development\GogoFans\gogofans-ui\node_modules@graphql-tools\code-file-loader\index.cjs.js:239:18)
at CodeFileLoader.load (C:\Development\GogoFans\gogofans-ui\node_modules@graphql-tools\code-file-loader\index.cjs.js:173:28)
at async loadFile (C:\Development\GogoFans\gogofans-ui\node_modules@graphql-tools\load\index.cjs.js:48:24)

GraphQLError: Syntax Error: Expected Name, found "}".

at syntaxError (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\error\syntaxError.js:15:10)
at Parser.expectToken (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:1423:40)
at Parser.parseName (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:92:22)
at Parser.parseField (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:289:28)
at Parser.parseSelection (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:278:81)
at Parser.many (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:1537:26)
at Parser.parseSelectionSet (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:265:24)
at Parser.parseFragmentDefinition (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:410:26)
at Parser.parseDefinition (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:134:23)
at Parser.many (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:1537:26)
at Parser.parseDocument (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:109:25)
at Object.parse (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:36:17)
at Object.parseGraphQLSDL (C:\Development\GogoFans\gogofans-ui\node_modules@graphql-tools\utils\index.cjs.js:601:28)
at parseSDL (C:\Development\GogoFans\gogofans-ui\node_modules@graphql-tools\code-file-loader\index.cjs.js:239:18)
at CodeFileLoader.load (C:\Development\GogoFans\gogofans-ui\node_modules@graphql-tools\code-file-loader\index.cjs.js:173:28)
at async loadFile (C:\Development\GogoFans\gogofans-ui\node_modules@graphql-tools\load\index.cjs.js:48:24)

Something went wrong

npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! gogofans-ui@0.0.0 generate: graphql-codegen --config codegen.yml
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the gogofans-ui@0.0.0 generate script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\Fidel\AppData\Roaming\npm-cache_logs\2020-07-06T07_01_25_424Z-debug.log

最佳答案

因为您的模式是静态的,所以字段不会改变。这意味着,您可以将所有可能的字段添加到您的选择集中,然后使用 @skip@include 指令对其进行过滤。

GraphQL Codegen 及其使用的工具不支持字符串插值,也不会增加对它的支持,因为为了获得最终的字符串,我们需要加载、编译并查找导出的标识符.这样做会使 codegen 的设置变得更加复杂 - 因为 JS 生态系统中有很多风格。

GraphQL 模式和操作可以定义为静态字符串,您应该能够使用指令或类似操作动态地控制选择集。

下面是一个使用内置 @skip@include 指令的示例,在片段展开上:

query UserProfileQuery($id: String!, $loadA: Boolean, $loadB: Boolean) {
      showUser(id: $id) {
        ...UserFieldsA @include(if: $loadA)
        ...UserFieldsB @include(if: $loadB)
      }
    }

fragment UserFieldsA {
  id
  a
}

fragment UserFieldsB {
  id
  b
}

这样,您可以在运行时通过从 JS 代码设置变量 $loadA$loadB 来动态控制它。

这些指令的定义与 GraphQL 中的一样:

directive @skip(if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT

directive @include(if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT

这意味着您可以在字段、片段展开或内联片段上使用它 - 因此它应该为您提供足够的灵 active 来管理复杂和动态的选择集。

关于angular - 带有插值的 graphql-codegen 动态场,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62749847/

相关文章:

angular - 如何在 Ionic 2 中使用 angular 2 服务?

typescript - JSON.stringify() 转义值的行结束字符

entity-framework - 如何处理数据加载器/GraphQL 嵌套查询中的并发 DbContext 访问?

python - 在 Python 中构造 GraphQL 查询字符串的最佳方法

javascript - templateUrl 中的相对 url 与 Angular 4 和 sails 不工作

javascript - 为什么向 Observable 添加属性时会出现 TypeError

javascript - 将多个用户图像上传到 Firestore 集合的最佳方法是什么?使用 Angular/Ionic 4

Typescript:模块作为返回类型?

graphql - 新 GraphQL buildSchema 的嵌套查询

angular - 如何使用返回值调用父方法 Angular 2?