Meteor React 教程第 4 步:任务勾选更新与删除(Update and Remove)
后端前端开发工具移动开发【免费下载链接】meteorMeteor, the JavaScript App Platform项目地址https://gitcode.com/gh_mirrors/me/meteor点击查看免费下载本步是 Meteor React 教程To-Do 应用的第四课目标是为任务列表接入更新与删除能力通过复选框切换任务的isChecked状态通过按钮删除指定任务。你将学会如何在客户端组件中接收回调、如何用Meteor.methods定义服务端方法、如何用Meteor.callAsync调用它们以及updateAsync/removeAsync这类异步集合 API 的底层行为。在开始之前你需要已经完成教程的前三步创建任务集合 2.collections.mdTasksCollection与tasks发布订阅、实现任务表单 3.forms-and-events.mdTaskForm与tasks.insert方法。到目前为止你只向集合插入过文档本步将围绕如何通过界面交互来更新和删除这些文档展开。4.1 为 Task 组件添加复选框首先在Task组件中加入一个checkbox元素。这里有两个关键细节需要注意必须添加readOnly属性因为我们不使用onChange来更新 React 状态复选框的勾选状态完全由数据驱动readOnly可以避免浏览器对复选框的内部状态管理干扰我们的受控组件逻辑。必须把checked属性强制转换为布尔值React 将undefined值视为该属性不存在这会导致组件从受控组件controlled意外切换为非受控组件uncontrolled。因此使用!!task.isChecked把可能不存在的isChecked字段规范化为true/false。同时为了让父组件App能感知点击事件组件需要接收一个回调函数onCheckboxClick在复选框被点击时以task为参数调用它import React from react; export const Task ({ task, onCheckboxClick }) { return ( li input typecheckbox checked{!!task.isChecked} onClick{() onCheckboxClick(task)} readOnly / span{task.text}/span /li ); };从源码结构看Task是一个纯展示型受控组件它不持有任何本地状态只把task文档和回调作为 props这保证了 UI 始终与集合数据保持一致。教程也鼓励你亲自实验一下比如去掉readOnly、或者去掉!!强制转换观察应用的受控/非受控行为差异能帮助你更深刻理解 React 受控组件。4.2 切换勾选状态tasks.toggleChecked 方法有了复选框接下来就需要让勾选真正写回数据库。为此在imports/api/tasksMethods.js中新增一个名为tasks.toggleChecked的 Meteor Method用于更新任务的isChecked属性import { Meteor } from meteor/meteor; import { TasksCollection } from ./TasksCollection; Meteor.methods({ .. tasks.toggleChecked({ _id, isChecked }) { return TasksCollection.updateAsync(_id, { $set: { isChecked: !isChecked }, }); }, });这里用到了MongoDB 更新操作符$set它只修改文档的isChecked字段而不会覆盖整条文档!isChecked表示将当前值取反实现切换语义。方法体返回的是updateAsync的 PromiseMeteor 会自动把方法返回值序列化回客户端。关于updateAsync它是Mongo.Collection提供的异步 APImethods_async.js签名是updateAsync(selector, modifier, options)。第一个参数selector指定要修改哪些文档这里直接传_id第二个参数modifier描述如何修改第三个可选参数options支持multi是否修改所有匹配文档默认只改一个、upsert没有匹配文档时是否插入新文档以及arrayFilters配合数组位置过滤器使用。返回值是匹配文档的数量。在Meteor.methods中服务端环境它会直接落到底层 MongoDB 驱动执行若在客户端远程集合上调用则会走_callMutatorMethodAsync经由 DDP 转发到服务端。在 App 组件中接入回调接下来在App组件中创建处理函数并通过onCheckboxClick传给每个Task.. export const App () { const handleToggleChecked ({ _id, isChecked }) Meteor.callAsync(tasks.toggleChecked, { _id, isChecked }); .. ul { tasks.map(task Task key{ task._id } task{ task } onCheckboxClick{handleToggleChecked} /) } /ul ..handleToggleChecked从被点击的任务对象中解构出_id和isChecked然后调用Meteor.callAsync——第一个参数是方法名第二个参数是要传给方法的数据。由于数据经useTracker订阅驱动方法执行成功后 MongoDB 文档变化会通过发布/订阅反应式地推回客户端组件自动重新渲染复选框即呈现新的勾选状态。Meteor.callAsync与旧式Meteor.call的关键区别它返回一个 Promise因此必须用await或.then()消费结果。从 livedata_connection.js 的实现看如果你试图传入回调函数它会直接抛出Meteor.callAsync() does not accept a callback...错误这是为了强制使用现代异步风格。Meteor 3 全面转向了这种基于 Promise/async 的编程模型。完成后应用效果如下图所示——前两个任务已被勾选4.3 删除任务tasks.delete 方法删除任务只需几行代码。在 Task 组件中添加删除按钮首先在Task组件中、任务文本之后添加一个按钮并接收新的回调onDeleteClickimport React from react; export const Task ({ task, onCheckboxClick, onDeleteClick }) { return ( .. span{task.text}/span button onClick{ () onDeleteClick(task) }times;/button ..times;是 HTML 实体渲染为乘号×是最常见的删除按钮样式。定义 tasks.delete 方法在imports/api/tasksMethods.js中新增tasks.delete方法按_id从集合中移除文档import { Meteor } from meteor/meteor; import { TasksCollection } from ./TasksCollection; Meteor.methods({ .. tasks.delete({ _id }) { return TasksCollection.removeAsync(_id); }, });关于removeAsync同样定义于 methods_async.js签名是removeAsync(selector, options)。selector可以是_id字符串、对象形式的查询选择器如{ isChecked: true }可一次删除多个文档或函数形式。实现中会先经过Mongo.Collection._rewriteSelector规范化选择器再决定走本地_collection.removeAsync还是远程 DDP 调用。返回值是被删除文档的数量。在 App 组件中组织删除逻辑然后在App中创建handleDelete函数调用tasks.delete并把onDeleteClick传给Taskexport const App () { .. const handleDelete ({ _id }) Meteor.callAsync(tasks.delete, { _id }); .. ul { tasks.map(task Task key{ task._id } task{ task } onCheckboxClick{handleToggleChecked} onDeleteClick{handleDelete} /) } /ul .. }点击任意任务右侧的×按钮该方法即在服务端删除对应文档订阅数据随后更新任务从列表中消失原理纵深Meteor Methods 的注册、调用与异步链回顾本步新增的两个方法tasks.toggleChecked和tasks.delete它们背后的完整调用链可以这样理解服务端注册Meteor.methods({ ... })由服务端 DDP 实现livedata_server.js处理。源码会遍历传入的每个方法校验其必须是函数若同名方法已存在method_handlers[name]已被占用则抛出A method named ... is already defined错误。因此方法名如tasks.toggleChecked在整个应用内必须唯一。客户端调用Meteor.callAsync(tasks.toggleChecked, { _id, isChecked })走客户端连接实现livedata_connection.js先执行客户端存根stub模拟再通过 DDP 协议将method消息发送到服务端服务端在method_handlers中查找并执行对应函数最后把结果返回客户端。整个过程可被await也便于用 try/catch 捕获错误。数据落地方法体内部的updateAsync/removeAsync在服务端直接操作 MongoDB由于客户端通过tasks发布订阅监听该集合文档变化经 oplog 观察或轮询机制被推回客户端useTracker触发 React 组件重新渲染——这正是操作数据库、UI 自动同步的完整闭环。安全边界把写操作封装在 Methods 中而非让客户端直接TasksCollection.updateAsync(...)是因为前者运行在服务端、受方法级权限控制可以检查this.userId、做参数校验而直连集合的写入insecure 模式下不受任何限制。这是 Meteor 应用服务端安全的惯例做法。有关 Methods 的更多细节可参见 methods.md 相关教程章节。本步小结与下一步至此你的 To-Do 应用已经具备完整的**增第 3 步的表单插入、查第 2 步的发布订阅渲染、改本步tasks.toggleChecked、删本步tasks.delete**能力并且全部通过 Meteor Methods 走安全的异步调用链完成。本步核心要点回顾目标涉及代码使用的 API勾选/取消任务Task.jsx复选框 App.jsx的handleToggleCheckedMeteor.callAsyncTasksCollection.updateAsync删除任务Task.jsx删除按钮 App.jsx的handleDeleteMeteor.callAsyncTasksCollection.removeAsync服务端方法定义imports/api/tasksMethods.jsMeteor.methods({ tasks.xxx() { ... } })下一步我们将使用 CSS 与 Flexbox 改善应用的视觉效果见 5.styles.md让这个 To-Do 应用在功能之外也具备整洁的外观。赞分享后端前端开发工具移动开发【免费下载链接】meteorMeteor, the JavaScript App Platform项目地址https://gitcode.com/gh_mirrors/me/meteor点击查看免费下载相关推荐从改一个金币到冻结整段内存EdiZon 让 Switch 存档修改不再劝退新手从改一个金币到冻结整段内存EdiZon 让 Switch 存档修改不再劝退新手 先问一个真实的问题当你在《塞尔达传说旷野之息》里翻山越岭攒了三天卢比却发后端前端开发工具移动开发Meteor 3 Svelte 实战任务更新与删除的完整实现Todo 应用第 4 步Meteor 3 Svelte 实战任务更新与删除的完整实现Todo 应用第 4 步 本篇教程以 Meteor 官方教程 Svelte 版的第 4 步后端前端开发工具移动开发Meteor 3 Solid 实战使用 Meteor Methods 更新与删除 MongoDB 任务数据Meteor 3 Solid 实战使用 Meteor Methods 更新与删除 MongoDB 任务数据 在 Meteor.js 3 结合 Solid后端前端开发工具移动开发上一篇《wgai开源AI平台的安装与使用教程》下一篇MailKit完整教程10个步骤从零开始掌握.NET邮件开发创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联
返回资讯列表 →