首页/新闻资讯/正文详情

HowToGraphQL Ember 教程详解:用 ember-apollo-client 发送 GraphQL Mutation 创建 Link

发布时间:2026/9/25 3:05:55 来源:云帆数科 栏目:资讯中心
HowToGraphQL Ember 教程详解:用 ember-apollo-client 发送 GraphQL Mutation 创建 Link
【免费下载链接】howtographqlThe Fullstack Tutorial for GraphQL项目地址https://gitcode.com/gh_mirrors/ho/howtographql点击查看免费下载本文基于 HowToGraphQL 教程仓库中 Ember Apollo 前端轨道的第三章文档 3-mutations-creating-links.md 展开完整讲解如何在 Ember 应用中通过ember-apollo-client插件的apolloservice 发送第一个 GraphQL Mutation——创建一条 Link 记录。读完后你将掌握用ember generate脚手架准备表单路由与控制器、在.graphql文件中定义带变量的 mutation 操作、通过mutate方法把表单数据提交到 GraphQL 服务端并用 Playground 验证数据真正落库的完整闭环。背景教程轨道与前置条件该文档属于 HowToGraphQL 的「Ember Apollo」前端轨道目标是构建一个 Hackernews 克隆应用。整条技术栈为前端Ember由ember-cli创建项目ember-apollo-client一个ember-cliadd-on向 Ember 暴露与 Apollo 交互的 service后端Graphcool 提供的 GraphQL API。前置章节 1-getting-started.md 已经完成了三件关键准备直接决定本文 mutation 能否跑通使用 Graphcool CLI注意教程声明使用的是 legacy 版本可用npm install -g graphcool0.4安装创建了只含Link类型的项目schema 如下type Link model { description: String! url: String! }运行ember install ember-apollo-client引入了插件在config/environment.js的ENV对象中配置了 GraphQL 端点ember-apollo-client据此初始化底层的ApolloClient// config/environment.js 的 ENV 对象内 apollo: { apiURL: __SIMPLE_API_ENDPOINT__ },而 2-queries-loading-links.md 则建立了本轨道数据获取的通用范式——把请求写在.graphql文件里import 进 JS 文件再用apolloservice 发送最终通过 Promise 拿到结果├── app │ ├── gql │ │ ├── queries │ │ ├── mutationsmutation 的处理流程与此完全同构这也是本文开篇强调的「发送 mutation 与发送 query 没有太大区别」的由来。准备应用创建 create 路由与表单模板mutation 需要一个入口页面让用户填写新链接的url和description。第一步是用 Ember 生成器创建路由# 在 hackernews-ember-apollo 项目根目录执行 ember generate route create生成器会创建app/routes/create.js、app/templates/create.hbs并在app/router.js中注册/create路由。文档明确要求删除生成的路由文件app/routes/create.js——因为这条路由不需要modelhook真正承载表单逻辑的将是下一步要创建的 controller生成器在这里的价值只是模板文件和路由注册。然后把app/templates/create.hbs替换为如下模板!-- app/templates/create.hbs -- div form classflex flex-column mt3 {{action createLink onsubmit}} {{input classmb2 typetext placeholderA description for the link valuedescription}} {{input classmb2 typetext placeholderThe URL for the link valueurl}} div classflex {{input typesubmit valuesubmit}} /div /form /div这是一个标准的两段式表单有三个值得注意的 Ember 模板要点{{action createLink onsubmit}}表单submit事件绑定到 controller 中名为createLink的 action。Ember 中模板 action 的解析规则是优先在当前 controller 的actionshash 中查找这解释了为什么本文的 mutation 逻辑最终写在 controller 而不是 component 里两个{{input}}辅助函数的valuedescription与valueurl是双向绑定表单输入会实时写入 controller 上同名的属性这是后续this.get(description)能取到最新值的依据CSS 类flex、mt3、mb2来自教程引入的 Tachyons 原子化样式库ember install ember-cli-tachyons-shim与业务逻辑无关。编写 Mutation 定义与 query 章节的allLinks.graphql一样mutation 也定义在独立的.graphql文件中。在app/gql/mutations文件夹该文件夹在前一章已随queries一并建好中新建createLink.graphql# app/gql/mutations/createLink.graphql mutation CreateLinkMutation($description: String!, $url: String!) { createLink(description: $description, url: $url) { id createdAt url description } }逐部分解读语法要素说明mutation CreateLinkMutation操作关键字 操作名operation name。操作名供 Apollo 在内部识别该操作例如在日志、缓存键、网络层中引用它与查询里的AllLinksQuery命名方式一致($description: String!, $url: String!)声明两个非空字符串变量。GraphQL 的类型系统在此处生效如果调用方漏传或传错类型服务端会在执行前直接报参数校验错误createLink(description: $description, url: $url)调用 Graphcool 根据Link模型自动生成的createLinkmutation 字段变量以命名参数方式绑定{ id createdAt url description }响应字段集。其中id、createdAt是 Graphcool 为每个模型自动维护的只读系统字段前文提到id带isUnique前端显式请求它们才能拿到新建记录的完整数据对比前序 query 文件的写法可以看出本轨道的约定queries/与mutations/目录一一对应文件名与 mutation 字段同名createLink.graphql操作名则以Mutation后缀区分。创建 Controller 并接入 mutate 方法模板已经声明了{{action createLink onsubmit}}接下来用生成器创建 controller 并实现该 actionember generate controller create然后在生成的app/controllers/create.js中写入如下代码教程按 1~6 编号了关键步骤此处保留// app/controllers/create.js import Ember from ember; // 1. 导入 .graphql 文件中定义的 mutation import mutation from hackernews-ember-apollo/gql/mutations/createLink; export default Ember.Controller.extend({ actions: { // 2. 模板中 {{action createLink}} 绑定到的 action createLink() { // 3. 读取双向绑定的表单值组装成 mutation 变量 const description this.get(description); const url this.get(url); let variables { description, url }; // 4. 调用 apollo service 的 mutate 方法发送 mutation return this.get(apollo) .mutate( { mutation, variables }, createLink ) .then(() { // 5. 成功后清空表单并跳转回列表路由 this.set(description, ); this.set(url, ); this.transitionToRoute(links); }).catch(error alert(error)); } }, // 6. 注入 ember-apollo-client 提供的 apollo service apollo: Ember.inject.service() });逐步拆解导入 mutationember-apollo-client的构建管线会把.graphql文件编译成 JS 模块并暴露文档字符串因此这里 import 到的mutation就是上一节定义的操作文档与 query 章节导入allLinks的方式完全一致定义 actioncreateLink是actionshash 中的方法模板提交时由 Ember 自动调用组装 variables从 controller 属性上读出表单值并打成{ description, url }字段名与 mutation 声明的变量一一对应调用mutate这是本节的核心 API。mutate接收两个参数第一个参数是 mutation 选项对象包含mutation操作文档和variables变量值第二个参数createLink是一个字符串指定返回数据中期望结果所在的字段路径。这正是本章配套测验的正确答案「mutate方法中的最后一个字符串指定了返回数据中你期望的数据所在的位置」。服务端响应形如{ data: { createLink: {...} } }传入createLink后Promise 直接 resolve 为该字段的内容处理 Promise 结果.then中清空表单状态并调用this.transitionToRoute(links)跳回列表页.catch中用alert展示错误。注意表单清空放在 resolve 之后而非提交之前可以避免请求失败时用户输入被意外丢失注入 serviceapollo: Ember.inject.service()把ember-apollo-client注册的全局apolloservice 注入 controller。service 底层持有配置好apiURL的ApolloClient实例query与mutate两个方法都由它暴露——前序 query 章节中this.get(apollo).query(...)与这里的mutate是同一 service 上的对等方法。与 query 用法的一个显著差异值得强调query 是在 route 的modelhook 中调用query由路由系统托管生命周期mutation 则由用户动作表单提交触发写在 controller 的 action 里生命周期由事件流管理。两者共享的是「.graphql文件 apollo service Promise」这一套基础设施。关于教程站代码块的 path 标注顺带一提本仓库站点源码揭示了教程文档中path.../hackernews-ember-apollo/app/...这类标注的渲染机制Pre.tsx 组件会解析path属性剥掉开头的.../与第一个路径段后拼出配套示例仓库的链接并在代码块右上角提供一键复制按钮nocopy参数可关闭而 Markdown.tsx 通过JsxParser把文档中的Instruction标签映射为 Instruction.tsx 渲染的蓝色边线「指令块」。也就是说本文展示的每一步「指令 代码」在站点上都是可复制、可跳转到配套项目文件的可交互元素。验证 Mutation 是否生效按教程步骤运行yarn start应用启动在http://localhost:4200导航到/create路由即可看到表单页两个输入框加一个 submit 按钮。填入示例数据后提交DescriptionThe best learning resource for GraphQLURLwww.howtographql.com此时要注意文档提示的一个细节在页面跳转之前 UI 上不会有任何视觉反馈因为本文的 mutation 还没有接入 Apollo 缓存更新update回调是后续章节的内容。要确认数据确实写入需要在另一个终端打开 Playgroundgraphcool playground该命令会读取project.graphcool中的项目 ID 并在浏览器打开交互式查询环境。在编辑器中发送查询{ allLinks { description url } }如果 mutation 工作正常右侧结果面板应返回包含新记录的数据{ data: { allLinks: [ { description: The best learning resource for GraphQL, url: www.howtographql.com } // ... ] } }至此完成了「表单 → controller action →.graphqlmutation 文档 →mutate调用 → 服务端落库 → Playground 回查」的完整验证链路。后续演进从 mutate 到缓存更新本文的 mutation 属于「提交后跳转」模式用户离开当前页新数据靠重新query加载才可见。在同一轨道的后续章节 6-more-mutations-and-updating-the-store.md 中教程给mutate的选项对象补上了update回调利用 Apollo 的 imperative store API 在 mutation 返回后手动读写缓存update: (store, { data: { createLink } }) { const data store.readQuery({ query: allLinks }); data.allLinks.splice(0, 0, createLink); store.writeQuery({ query: allLinks, data }); }即把新建的createLink直接插入allLinks缓存结果的最前部再写回 store这样用户跳回列表页时新链接立即可见无需等待重新请求。这说明本文建立的mutate({ mutation, variables }, 字段路径)调用骨架是稳定的演进方向只是在选项对象中叠加缓存控制逻辑。从结构大纲看参见同仓库的 meta/structure/react-apollo.md其「4. Mutations → Mutation: Creating Links」小节与本文脉络一致「创建 Link 的 mutation」也是各前端轨道共用的标准教学节点便于在不同框架实现之间横向对照。小结本文覆盖 3-mutations-creating-links.md 的全部实操步骤并补齐了上下文用ember generate route create建路由并删除多余的路由文件模板create.hbs中用{{action createLink onsubmit}}与双向绑定的{{input}}搭好表单在app/gql/mutations/createLink.graphql中定义带String!非空变量的CreateLinkMutation操作名与 query 文件遵循同一命名约定通过ember generate controller create创建控制器在createLinkaction 中读取表单值、组装variables调用this.get(apollo).mutate({ mutation, variables }, createLink)发送请求——第二个参数指定响应数据中期望结果的字段路径Promise resolve 后清空表单并transitionToRoute(links)用graphcool playground发送allLinks查询确认新记录已入库该调用骨架可直接延伸到后续章节的update缓存更新回调形成 mutation 提交与客户端缓存同步的完整方案。适用前提提醒本教程基于 Graphcool legacy 版 CLIgraphcool0.4与ember-apollo-client早期特性集如文档所述尚未完整支持 subscriptions文中的 CLI 命令与端点获取方式均以 1-getting-started.md 中的声明为准。赞分享【免费下载链接】howtographqlThe Fullstack Tutorial for GraphQL项目地址https://gitcode.com/gh_mirrors/ho/howtographql点击查看免费下载相关推荐HowToGraphQL 实战用 Ember Apollo Client 搭建 Hacker News 克隆应用的前端基础HowToGraphQL 实战用 Ember Apollo Client 搭建 Hacker News 克隆应用的前端基础 本文基于 HowToGraphHow to GraphQLAngular Apollo 中使用 GraphQL Mutation 创建 Link 的完整实现How to GraphQLAngular Apollo 中使用 GraphQL Mutation 创建 Link 的完整实现 本篇基于 How to GJina Client 发送 GraphQL Mutation用法、参数与实现原理Jina Client 发送 GraphQL Mutation用法、参数与实现原理 本文围绕 Jina 仓库中 docs/concepts/client/se后端人工智能模型推理服务微服务上一篇react-bits 第三方库集成指南用生命周期隔离 React 与 jQuery 插件的 DOM 控制权下一篇PC 微信/QQ/TIM 防撤回补丁 4 步装好实战被撤回的消息不再消失创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

Learn-Algorithms 链表排序专题:单链表归并排序、相交检测与环入口定位
Learn-Algorithms 链表排序专题:单链表归并排序、相交检测与环入口定位

教程 【免费下载链接】Learn-Algorithms 算法学习笔记 项目地址: https://gitcode.com/gh_mirrors/le/Learn-Algorithms 点击查看 免费下载 导读:本文围绕仓库 9 Algorithms Job Interview/2.1 链表-排序.md 中记录的微软面试题展开——给定单链表头指针… · 2026/9/25 3:05:55

SAP安全审计日志实战:SM19配置与SM20查询全指南
SAP安全审计日志实战:SM19配置与SM20查询全指南

做 SAP 运维这些年,被问得最多的问题之一就是:“帮我查一下某某用户昨天登录了系统没有?他到底跑了哪些事务码?”每次接到这类需求,我第一反应就是打开 SM19 和 SM20 这对组合。很多顾问平时不太碰这两个事务码&#x… · 2026/9/25 3:05:55

使用宝塔面板部署 MediaGo:Docker 应用商店一键安装与服务端口详解
使用宝塔面板部署 MediaGo:Docker 应用商店一键安装与服务端口详解

音视频桌面应用后端 【免费下载链接】mediago 跨平台视频提取工具:支持流媒体下载、视频下载、m3u8 下载及 B站视频下载,提供 Windows 和 Mac 桌面客户端。Cross-platform video extraction tool: Supports streaming download, video download, m3u8 do… · 2026/9/25 3:05:49

为什么地址是0x13?深入解析ps2-controller背后PS2手柄I2C通信原理
为什么地址是0x13?深入解析ps2-controller背后PS2手柄I2C通信原理

为什么地址是0x13?深入解析ps2-controller背后PS2手柄I2C通信原理 【免费下载链接】ps2-controller 源师兄扩展项目: PS2 | 由源师兄组织创建 项目地址: https://gitcode.com/yuanshixiong/ps2-controller 在 ps2-controller 这款源师兄出品的 PS2 手柄 I2C … · 2026/9/25 3:29:40

华为云与腾讯云怎么选?从云原生到信创的全场景决策指南
华为云与腾讯云怎么选?从云原生到信创的全场景决策指南

前阵子有个朋友找我做选型咨询,他们要做一个面向连锁餐饮企业的数据分析中台,既要卖软件又要做交付,甲方那边点名要“信创”。朋友打开两个网页问我:华为云和腾讯云到底差在哪?参数表我看得头晕,你直接告诉… · 2026/9/25 3:29:40

PCI简易通讯控制器黄标修复全指南
PCI简易通讯控制器黄标修复全指南

1. 黄色感叹号不是故障,而是Windows在向你发求救信号“PCI简易通讯控制器”这个名称听起来很陌生,但只要你打开设备管理器,展开“系统设备”或“其他设备”,大概率会看到它——一个带着黄色感叹号的灰色图标,名字里带着… · 2026/9/25 3:29:34

JobOps AI Provider配置终极对比:OpenAI、Claude还是Ollama本地部署免费方案
JobOps AI Provider配置终极对比:OpenAI、Claude还是Ollama本地部署免费方案

JobOps AI Provider配置终极对比:OpenAI、Claude还是Ollama本地部署免费方案 【免费下载链接】job-ops job-ops: DevOps principles applied to job hunting. A self-hosted pipeline to track, analyze, and assist your application process 项目地址: https://… · 2026/9/25 3:29:34

JVM执行引擎解析:解释器与JIT编译器优化实战
JVM执行引擎解析:解释器与JIT编译器优化实战

1. JVM执行引擎的双剑合璧:解释器与JIT编译器第一次接触Java时,我就被"一次编写,到处运行"的特性所吸引。直到深入JVM内部,才发现这个魔法背后是解释器与JIT编译器这对黄金搭档的完美配合。在实际工作中,我经… · 2026/9/25 3:29:28

OpenUsage如何把Token日志算成美元?模型定价引擎深度解析
OpenUsage如何把Token日志算成美元?模型定价引擎深度解析

OpenUsage如何把Token日志算成美元?模型定价引擎深度解析 【免费下载链接】openusage Burning through your subscriptions too fast? Paying for stuff you never use? Stop guessing. OpenUsage is free and open source. 项目地址: https://gitcode.com/gh_m… · 2026/9/25 3:29:28

数值优化(Numerical Optimization)学习系列-03-共轭梯度方法(Conjugate Gradient)
数值优化(Numerical Optimization)学习系列-03-共轭梯度方法(Conjugate Gradient)

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:31

创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战
创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:31

MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX
MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:37

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码