AngularJS任务管理应用:点击按钮展示对应子任务异常求助
问题分析
你遇到的核心问题是所有任务共享了同一个全局的$scope.subTasks变量。当你点击某个任务的"+"按钮时,会把获取到的子任务赋值给这个全局变量,而页面上所有任务的子任务列表都绑定了这个变量,所以所有任务都会显示相同的子任务。另外还有几处拼写/字段匹配的细节错误需要修正。
解决方案
我们需要让每个任务拥有自己独立的子任务集合和展开状态,具体步骤如下:
1. 先修正拼写与字段匹配的基础错误
- 你的HTML中
ng-click="showTasks(task._id)",但控制器里定义的方法是showsubTasks,名字不匹配,先统一成规范的showSubTasks。 - 你的Mongoose Schema里子任务字段是
subTasks,但后端路由里写的是sub_tasks,字段名不匹配,后续要把路由里的查询字段改成subTasks。 - 你的Schema最后导出时写错了模型关联的Schema,要改成绑定
taskSchema。
2. 给每个任务添加独立的子任务和展开状态
修改控制器的showSubTasks方法,不再使用全局$scope.subTasks,而是把获取到的子任务赋值给对应的task对象,同时添加isExpanded属性控制子任务的显示隐藏:
var app = angular.module('dashboard', []); app.controller('dashboardCtrl', function($scope, $http, $window){ // 获取所有任务 var refresh = function() { $http.get('api/tasks').then(function(response) { $scope.tasks = response.data; console.log("任务数据获取成功"); }); }; refresh(); // 获取指定任务的子任务并绑定到当前任务对象 $scope.showSubTasks = function(task){ // 切换展开状态:如果已经展开就收起,否则获取子任务并展开 if(task.isExpanded){ task.isExpanded = false; return; } $http.get('api/task/'+ task._id).then(function(response) { console.log("子任务数据获取成功"); // 把子任务赋值给当前task的专属属性 task.subTasks = response.data.subTasks; // 标记当前任务为展开状态 task.isExpanded = true; }); } })
3. 修改HTML模板,绑定当前任务的子任务和展开状态
把原来的全局subTasks遍历改成当前task的subTasks,并通过ng-if控制仅展开时显示:
<body ng-app="dashboard"> <div class="container list-group list-group" ng-controller="dashboardCtrl"> <ul ng-repeat="task in tasks" class="list-group-item list-group-item-action"> <li class="list_style"> <span>{{task.name}}</span> <span>{{task.description}}</span> <span><button class="btn btn-danger" ng-click="remove(task._id)">Delete</button></span> <span><button class="btn btn-info" ng-click="edit(task._id)">Edit</button></span> <span><button class="btn btn-info" ng-click="addTask(task._id)">Add new task</button></span> <span><button class="btn btn-success" ng-click="showSubTasks(task)">+</button></span> </li> <!-- 仅当当前任务展开且有子任务时显示 --> <ul ng-if="task.isExpanded && task.subTasks" class="list-group-item list-group-item-action active" style="margin-top: 10px;"> <li ng-repeat="subTask in task.subTasks"> <p>{{subTask.name}}</p> <p>{{subTask.description}}</p> <p>{{subTask.due_date}}</p> </li> </ul> </ul> </div> </body>
4. 修正后端路由与Schema的错误
后端路由修正
把查询字段改成和Schema一致的subTasks:
// 获取所有任务 router.get("/tasks", (req,res)=>{ task.find((err, tasks)=>{ if(err) { console.error(err); res.status(500).json({error: "获取任务失败"}); return; } res.json(tasks); }); }); // 获取指定任务的子任务 router.get("/task/:id", (req,res)=>{ task.findOne({_id:req.params.id}, 'subTasks', (err, task)=>{ if(err) { console.error(err); res.status(500).json({error: "获取子任务失败"}); return; } res.json(task); }); });
Schema导出修正
把最后一行的模型关联改成正确的taskSchema:
const mongoose=require("mongoose"); const taskSchema=mongoose.Schema({ name:{ type: String, required: true }, description:{ type: String, required: true }, subTasks:[{ name:{ type: String, required: true }, description:{ type: String, required: true }, due_date:{ type: String, required:true } }] }); const Task = module.exports = mongoose.model("Task", taskSchema);
为什么这样修改?
- 每个任务对象独立存储自己的子任务和展开状态,彻底避免了全局变量的冲突,点击某个任务只会更新该任务的子任务区域。
- 通过
isExpanded属性实现了点击按钮切换展开/收起的交互,提升了用户体验。 - 修正了所有拼写和字段匹配错误,确保数据能正确从后端获取并展示到前端。
内容的提问来源于stack exchange,提问作者drin
相关产品推荐
相关产品推荐

