路线筛选以后详情跳错了,城市探索页别再保存数组下标

发布时间:2026/10/14 17:38:55

路线筛选以后详情跳错了,城市探索页别再保存数组下标 城市路线列表在只有三条数据时用下标保存选中项看不出问题。加入距离筛选以后原本排在第二位的“老城咖啡线”可能变成第一位详情区域仍读取routes[1]画面便跳到另一条路线。城市步行探索的页面状态目前用selectedItem: number表示场景列表选择。这个写法适合静态演示继续加入搜索、距离排序和完成进度后就不够稳定。我把选择状态改成路线 ID过滤只改变可见集合不改变用户正在查看的对象。路线、地标和进度分别建模路线定义是相对稳定的内容用户进度会持续变化两者不应揉进同一个可变数组。exportinterfaceLandmark{id:stringname:stringorder:numberlatitude:numberlongitude:number}exportinterfaceWalkRoute{id:stringtitle:stringdistanceMeters:numbertags:string[]landmarkIds:string[]}exportinterfaceRouteProgress{routeId:stringvisitedLandmarkIds:string[]startedAt:numberupdatedAt:number}exportinterfaceRouteFilter{keyword:stringmaxDistanceMeters:numbertag:string}地标坐标属于路线内容是否到访属于进度。用户重新开始路线时只需要替换RouteProgress不用复制一遍地标列表。真实定位能力尚未接入时也可以通过本地按钮模拟到访验证进度计算和界面刷新。过滤结果不拥有选中状态控制器保留完整路线数组和selectedRouteId。搜索结果每次计算详情则始终回到完整数据中按 ID 查找。exportclassRouteExplorerController{privateroutes:WalkRoute[][]privatefilter:RouteFilter{keyword:,maxDistanceMeters:10000,tag:}privateselectedRouteId:stringsetRoutes(routes:WalkRoute[]):void{this.routesroutes.slice()if(!this.routes.some((item:WalkRoute)item.idthis.selectedRouteId)){this.selectedRouteIdthis.routes.length0?this.routes[0].id:}}updateFilter(next:RouteFilter):void{this.filter{...next}}visibleRoutes():WalkRoute[]{constkeywordthis.filter.keyword.trim().toLocaleLowerCase()returnthis.routes.filter((route:WalkRoute){constmatchKeywordkeyword.length0||route.title.toLocaleLowerCase().includes(keyword)constmatchDistanceroute.distanceMetersthis.filter.maxDistanceMetersconstmatchTagthis.filter.tag.length0||route.tags.includes(this.filter.tag)returnmatchKeywordmatchDistancematchTag})}selectRoute(routeId:string):boolean{if(!this.routes.some((item:WalkRoute)item.idrouteId)){returnfalse}this.selectedRouteIdrouteIdreturntrue}selectedRoute():WalkRoute|undefined{returnthis.routes.find((item:WalkRoute)item.idthis.selectedRouteId)}}筛选后选中路线可能暂时不可见。我没有立即把它改成结果第一项因为用户清除筛选时通常希望回到刚才的路线。页面可以显示“当前路线不在筛选结果中”由用户明确选择其他路线。ArkUI 列表键也使用路线 IDForEach若用数组下标做键排序后组件实例可能被复用到另一条数据。路线卡片使用route.id高亮条件也比较 ID。BuilderrouteList(routes:WalkRoute[]){Column({space:12}){ForEach(routes,(route:WalkRoute){Row({space:14}){Column({space:5}){Text(route.title).fontSize(17).fontWeight(FontWeight.Bold)Text(${(route.distanceMeters/1000).toFixed(1)}km ·${route.landmarkIds.length}个地标).fontSize(12)}.layoutWeight(1).alignItems(HorizontalAlign.Start)Text(route.tags[0]??城市漫步).fontSize(12)}.padding(16).backgroundColor(this.selectedRouteIdroute.id?#2AFFFFFF:#102536).border({width:this.selectedRouteIdroute.id?1:0,color:#4DB9FF}).borderRadius(20).onClick((){this.selectedRouteIdroute.id})},(route:WalkRoute)route.id)}}页面原有“滨江艺术线 2.4 km”“老城咖啡线 1.8 km”“夜景天桥线 3.1 km”都可以转换成WalkRoute。当按距离排序时只是传给routeList的顺序发生改变选中的 ID 不变。地标到访需要幂等定位回调可能连续命中同一地标。如果每次都向数组追加 ID页面会显示超过 100% 的完成度。更新进度前先判断是否已经存在。exportfunctionmarkVisited(progress:RouteProgress,landmarkId:string,now:number):RouteProgress{if(progress.visitedLandmarkIds.includes(landmarkId)){returnprogress}return{...progress,visitedLandmarkIds:[...progress.visitedLandmarkIds,landmarkId],updatedAt:now}}exportfunctioncompletion(route:WalkRoute,progress?:RouteProgress):number{if(!progress||route.landmarkIds.length0){return0}constvalidVisitednewSet(progress.visitedLandmarkIds.filter((id:string)route.landmarkIds.includes(id)))returnMath.round(validVisited.size/route.landmarkIds.length*100)}完成度只统计仍属于当前路线的地标。路线内容更新、删除某个地标后旧进度不会把比例撑高。这里使用经纬度只是为了说明数据边界并没有声称已完成真机定位验证。页面重建时恢复的是 ID应用进入后台或窗口重建时需要保存筛选条件、选中路线 ID 和路线进度。保存下标没有意义因为下次启动的路线排序可能已经变化。exportinterfaceExplorerSnapshot{selectedRouteId:stringfilter:RouteFilter progressList:RouteProgress[]savedAt:number}exportfunctionrestoreSelection(snapshot:ExplorerSnapshot,routes:WalkRoute[]):string{if(routes.some((route:WalkRoute)route.idsnapshot.selectedRouteId)){returnsnapshot.selectedRouteId}returnroutes.length0?routes[0].id:}页面的蓝色主题、三条路线和顶部标签切换保留原来的视觉结构数据层改为使用稳定 ID。下一步接入本地路线存储再由定位适配器上报地标到访事件。无论搜索、排序还是窗口重建详情都能继续指向用户真正选中的路线。
延伸阅读

更多相关文章

2026/10/10 12:06:43

立体空间应用

立体空间应用随着城市地面交通资源趋于饱和、城乡公共服务资源分布不均、传统产业巡检效率偏低等社会问题日益凸显,依靠地面维度的发展模式已经难以满足现代社会高效运转的需求。长期以来,人类的生产、运输、服务、治理活动高度集中于地面空间&#xff0…

2026/10/15 7:13:17

deque、priority_queue与仿函数:STL容器适配器实战解析

如果你在 C 里写过一段时间,一定遇到过这样的对话:某次代码评审里,同事指着deque说“这个不是双端队列嘛,当栈用也行”,又有人用priority_queue做定时器任务队列,结果排序规则写反,整个调度直接…

2026/10/15 7:13:17

藏区特产电商平台毕业设计全复盘:从表设计到订单状态机实现

做了很多年开发,看过不少学生的毕设选题,印象最深的不是那些复杂炫技的系统,而是我当年自己做的“藏区特产销售平台”这个毕业设计。当时就想着,与其再去做一个千篇一律的图书商城、二手交易平台,不如扎进一个真实存在…

2026/10/15 7:13:17

Claude Code完全指南:从安装配置到自动化重构的终端AI编程助手

最近在改一个老项目,数据库连接方式要从头换一遍,光受影响的文件我在全局搜索里数了数,快四十个。以前碰到这种杂活,我都是泡杯咖啡,开好几个编辑器分屏,一个文件一个文件地改,改完还得编译、跑…

2026/10/15 7:13:17

AI编程协作工作流:任务驱动的工程化实践指南

1. 项目概述:这不是一份“教程”,而是一套可复用的AI编程协作工作流“2 万 Star,我的 AI 编程教程被豆包推荐了!”——看到这个标题,很多开发者第一反应是点开找链接、抄代码、速成。但作为连续三年带团队落地AI辅助开…

2026/10/15 7:13:17

最新V1.5.rar解压与运行全指南:从校验到部署的工程实践

简介:科东纵向加密客户端V1.5是面向电力系统运维与安全技术人员的一款安全通信工具,配合科东PSTunnel2000加密装置使用,用于解决调度指令、电网运行状态等敏感数据在跨区域、跨层级网络节点间传输时的保密与防篡改问题。资源以rar压缩包形式提…

2026/10/15 7:08:16

YOLOv8路面裂缝检测系统开发实践:从数据到部署全流程

我已经在多个项目里用过YOLO系列做视觉检测,但真正让我觉得“这套流程可以沉淀下来复用”的,还是最近完成的这个路面裂缝检测系统。起因是某交通巡检项目需要把道路裂缝从现场照片里自动识别出来,效率要求接近实时,同时还得应付不…

2026/10/14 11:31:03

Python调用Gemini Structured Outputs实现工单路由门禁

客服工单最怕的不是模型“答错一句话”,而是它给出一段看起来合理的说明,程序却从中猜错优先级。通俗做法是:要求模型只交 JSON(JavaScript Object Notation,轻量数据格式),再让代码验证它。Gem…

2026/10/14 17:41:07

Spring Boot超市进销存系统毕设实战:从需求拆解到答辩通关

最近带的一个学生项目组里,有A同学跑来问我:选什么毕设题目最稳妥,既能让评审老师觉得工作量够,又不会在答辩时被问到语无伦次。我第一反应就是推荐基于Spring Boot的超市仓库管理系统——也就是超市进销存系统。这个题目乍一看平…

2026/10/14 2:32:55

Flutter StatefulWidget 生命周期核心解析

很多刚开始接触 Flutter 的朋友,在看完一堆“Hello World”和基础组件之后,大概率都会撞上同一堵墙:StatefulWidget 里那堆 initState、build、dispose 方法,到底什么时候被调用?为什么顺序是那样?在里面到…

2026/10/15 0:02:22

防关联浏览器哪个好?三款产品实测差异解析

新手做多店铺,最纠结的就是防关联浏览器选哪个。飞跨、网易、站斧这三款被问得最多,先给结论:要一体化省心、长期便宜,选站斧;要网易招牌和稳,选网易;预算紧做东南亚 Lazada,选飞跨。…

2026/10/15 0:02:22

影刀RPA深度实战:大模型Fine-tuning定制RPA专用Prompt与指令生成

影刀RPA深度实战:大模型Fine-tuning定制RPA专用Prompt与指令生成 一、技术背景 大模型(LLM)在通用场景下表现强大,但当我们将 GPT-4 或 Qwen 直接用于生成影刀RPA操作指令和 XPath 定位时,准确率通常只有 40%-60%。原因…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑