ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Web-Dev-For-Beginners 银行应用实战:实现「添加交易」对话框并接入状态管理

Web-Dev-For-Beginners 银行应用实战:实现「添加交易」对话框并接入状态管理 Web-Dev-For-Beginners 银行应用实战实现「添加交易」对话框并接入状态管理【免费下载链接】Web-Dev-For-Beginners24 Lessons, 12 Weeks, Get Started as a Web Developer项目地址: https://gitcode.com/GitHub_Trending/we/Web-Dev-For-Beginners本指南围绕 Web-Dev-For-Beginners 课程中银行应用7-bank-project第四课的课后作业展开为已完成状态管理与数据持久化的应用补齐「添加交易」Add Transaction功能。你将学到如何设计可访问的模态对话框、构造交易表单、对接后端 API并让新增交易通过既有状态管理系统即时刷新仪表盘。读完本文你可以独立完成从按钮、对话框、表单到 API 与状态层整合的完整功能闭环并掌握可复用的 Web 无障碍与前端架构实践。作业背景与学习目标银行应用此刻已经具备集中式状态管理state对象 updateState()受控更新、localStorage 持久化以及数据刷新机制但还缺少真实银行应用的关键能力让用户自己录入交易。本作业将四个银行课的核心知识点串成一条完整链路——HTML 模板、表单处理、API 集成与状态管理详见 第四课讲义 与前三课内容。完成本作业后你将能够创建一个用户友好的数据录入对话框界面实现支持键盘与屏幕阅读器的可访问表单设计整合新功能与既有状态管理系统实践API 通信与错误处理应用现代 Web 开发模式解决真实场景需求。前置条件环境与 API 就绪检查作业建立在第四课之前完成的代码之上动手前请确认环境就绪完成 数据获取课程应用能正常加载并展示账户数据安装 Node.js 用于运行后端 API参照 服务器 API 说明 在本地启动 API进入7-bank-project/api目录执行npm install随后npm start服务监听5000端口注意与主应用所在终端并存不要关闭。用一条命令验证 API 是否正常运行curl http://localhost:5000/api # - 应返回 Bank API v1.0.0这条命令会向本地 API 发送 GET 请求、测试连接若一切正常则返回 API 版本信息。仓库自带的 server.js 中GET /路由正是返回pkg.description v pkg.version即响应内容的来源。Step 1在仪表盘放置「添加交易」按钮在仪表盘页面上创建一个用户容易发现、方便使用的按钮要求位置合理放在仪表盘的逻辑位置如交易列表标题区文案清晰使用面向操作的按钮文本风格一致样式与现有 UI 设计统一键盘可达确保按钮可被键盘聚焦操作。参考实现中按钮被放在交易列表标题栏右侧使用内联onclick调起对话框。对应的 HTML 位于 solution/index.htmldiv classtransactions-title h2 idtransactions-descriptionTransactions/h2 button classbtn btn-primary typebutton onclickaddTransaction() i classfa-solid fa-plus aria-hiddentrue/i Add transaction /button /div注意图标使用aria-hiddentrue避免屏幕阅读器朗读装饰性图标按钮本身是原生button天然支持键盘 Tab 聚焦与 Enter/Space 触发。Step 2对话框实现——独立页面还是模态框作业提供两种实现路径推荐后者方案 A独立页面为交易表单创建新的 HTML 模板在路由系统中新增一条路由实现进入/返回表单页的导航。方案 B模态对话框推荐用 JavaScript 控制对话框的显示/隐藏不离开仪表盘页面使用 HTML 的hidden属性 或 CSS 类实现显隐通过正确的焦点管理营造流畅的用户体验。参考实现采用方案 B对话框默认带hidden属性配合.dialog样式display: none通过addTransaction()添加.show类display: flex来展示。核心结构见 solution/index.htmlsection idtransactionDialog classdialog hidden div classdialog-backdrop>function addTransaction() { const dialog qs(transactionDialog); if (!dialog) return; dialog.classList.add(show); const form qs(transactionForm); if (form) { form.reset(); form.date.valueAsDate new Date(); // 日期默认今天 form.date.focus(); // 焦点移到第一个字段 } const backdrop dialog.querySelector([data-dismiss]) || dialog; backdrop.addEventListener(click, onDialogDismissClick); dialog.addEventListener(keydown, onDialogKeydown); } function onDialogKeydown(e) { if (e.key Escape) { cancelTransaction(); } } function cancelTransaction() { const dialog qs(transactionDialog); if (!dialog) return; dialog.classList.remove(show); dialog.removeEventListener(keydown, onDialogKeydown); const opener document.querySelector(button[onclickaddTransaction()]); if (opener) opener.focus(); // 焦点归还触发按钮 }屏幕阅读器支持为对话框添加合适的 ARIA 角色与标签roledialog、aria-modaltrue、aria-labelledby指向标题与aria-describedby指向说明文字向读屏软件通告对话框的开/关状态为表单字段提供清晰的标签与错误信息。表单错误区使用rolealertaria-livepolite组合见 solution/index.html错误写入时读屏会自动播报错误设置函数setFormError()还会将焦点移到错误元素上方便键盘用户立刻定位问题function setFormError(id, message) { updateElement(id, message); const el qs(id); if (el) el.focus(); }Step 4交易表单的创建与校验表单需要收集三类必填数据字段含义输入规则日期Date交易发生时间input typedate required默认今天描述Object交易用途文本maxlength50必填金额Amount交易金额正数为收入credit负数为支出debitstepany支持小数参考表单结构solution/index.htmlform idtransactionForm actionjavascript:void(0) novalidate label fordateDate/label input iddate namedate typedate required label forobjectObject/label input idobject nameobject typetext maxlength50 required label foramountAmount (negative for debit)/label input idamount nameamount typenumber value0 stepany inputmodedecimal required div idtransactionError classerror rolealert aria-livepolite/div ... /form表单特性要求提交前校验用户输入、对非法数据给出明确错误信息、提供有助益的占位文本与标签、样式与现有设计一致。novalidate关闭浏览器原生气泡校验改由 JS 统一内联校验保证错误信息可控且能被读屏正确播报。confirmTransaction()solution/app.js中的校验逻辑与后端保持同一套规则——金额必须是有限数值、描述不可为空const amountVal Number(form.amount.value); const objectVal String(form.object.value || ).trim(); if (!Number.isFinite(amountVal)) { setFormError(transactionError, Amount must be a valid number); return; } if (!objectVal) { setFormError(transactionError, Object is required); return; }Step 5API 集成——端点、数据格式与错误处理作业要求对接后端 API正确端点与数据格式以 服务器 API 文档 为准方法路由说明GET/api/获取服务器信息POST/api/accounts/创建账户如{ user: Yohan, description: My budget, currency: EUR, balance: 100 }GET/api/accounts/:user获取指定账户全部数据DELETE/api/accounts/:user删除账户POST/api/accounts/:user/transactions添加交易如{ date: 2020-07-23T18:25:43.511Z, object: Bought a book, amount: -20 }DELETE/api/accounts/:user/transactions/:id删除指定交易本作业使用的端点即POST /api/accounts/:user/transactions请求体 JSON 字段为date、object、amount。后端实现server.js的细节可以帮助你理解预期行为账户不存在返回404 { error: User does not exist }缺少date/object/amount任一字段返回400 { error: Missing parameters }金额不是有效数字返回400 { error: Amount must be a number }服务端用 md5 对date object amount生成交易 ID重复内容返回409 { error: Transaction already exists }成功时以201返回新建的交易对象{ id, date, object, amount }并同步更新账户余额。注意仓库中的 server.js 将数据保存在内存中含预置的test账户重启即丢失仅用于教学演示。前端把表单数据序列化为 JSON 并提交solution/app.jsconst jsonData JSON.stringify(Object.fromEntries(new FormData(form))); const data await createTransaction(state.account.user, jsonData); if (data.error) { setFormError(transactionError, data.error); return; }错误处理要点成功/失败消息都要呈现给用户对网络错误要优雅降级如提示后允许重试服务端返回的error字段应直接映射到表单错误区。Step 6状态管理集成——新交易立即上屏这是把整个功能与既有架构缝合的关键一步要求成功添加交易后刷新账户数据仪表盘显示无需整页刷新即可更新新交易立即出现在交易列表全程保持状态一致性。参考实现没有重新拉取全量数据而是基于当前state.account以不可变更新方式本地合成新账户状态solution/app.jsconst newAccount { ...state.account, balance: (Number(state.account.balance) || 0) data.amount, transactions: [...(state.account.transactions || []), data] }; updateState(account, newAccount); cancelTransaction(); updateDashboard();关键点在于复用第四课建立的受控更新入口updateState()solution/app.jsfunction updateState(property, newData) { state Object.freeze({ ...state, [property]: newData }); localStorage.setItem(storageKey, JSON.stringify(state.account)); }由于所有状态变更都收敛到这一个函数持久化只需要一行代码写入 localStorage 自动完成updateDashboard()重读state.account后立即把余额与最新交易渲染上屏solution/app.js交易按日期倒序排列负数行加debit、正数行加credit样式类。如果希望更贴近「从服务器拿最新数据」的模式第四课还提供了updateAccountData()refresh()机制并挂到路由init上见 第四课讲义 的 Data Refresh 小节可作为本作业的进阶选择——在提交成功后调用refresh()以服务器返回为准更新仪表盘。预期结果完成六个步骤后应用应具备一个外观与行为都专业、可用的「添加交易」功能。下方是仓库提供的示例效果图测试你的实现功能测试验证「添加交易」按钮清晰可见且可访问测试对话框能正确打开与关闭确认所有必填字段的校验都生效检查成功提交的交易能立即出现在仪表盘确保非法数据与网络问题的错误处理都正常工作。无障碍测试仅用键盘走完整个流程用屏幕阅读器验证读屏通告是否正确验证焦点管理正常打开时聚焦表单、关闭后回到触发按钮检查所有表单元素都有合适的标签。评价标准标准优秀合格待改进功能性添加交易功能完美运行用户体验出色遵循课程全部最佳实践功能正确但可能未遵循部分最佳实践或有轻微可用性问题功能部分可用或有明显可用性问题代码质量组织良好遵循既定模式错误处理正确与既有状态管理无缝整合可运行但存在组织问题或与既有代码风格不一致结构性缺陷或与既有模式整合不佳可访问性完整键盘导航支持、读屏兼容遵循 WCAG 指南焦点管理出色基础无障碍已实现但缺少部分键盘或读屏特性几乎没有或完全没有考虑无障碍用户体验直观精致的界面反馈清晰交互流畅外观专业体验良好但反馈或视觉设计有小幅提升空间体验差界面令人困惑或缺少用户反馈附加挑战可选完成基础要求后可尝试以下增强功能增强增加交易分类餐饮、交通、娱乐等实现带实时反馈的输入校验为熟练用户提供键盘快捷键增加交易编辑与删除能力。进阶集成实现最近添加交易的撤销undo功能支持从 CSV 文件批量导入交易提供交易搜索与筛选实现数据导出。这些可选功能将帮助你练习更进阶的 Web 开发概念并让银行应用更加完整。若想进一步练习状态管理第四课讲义的 GitHub Copilot Agent Challenge 还提供了带撤销/重做与历史上限的状态管理挑战可作为本作业的自然延伸。【免费下载链接】Web-Dev-For-Beginners24 Lessons, 12 Weeks, Get Started as a Web Developer项目地址: https://gitcode.com/GitHub_Trending/we/Web-Dev-For-Beginners创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表