You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

点击Project实例时如何渲染任务数组?Todo列表任务添加异常求助

修复Todo列表中任务无法添加到选中项目的问题

核心问题梳理

你的代码里任务没法正确关联到选中的项目,主要是这几个关键错误:

  • 全局project变量是个空的新Project实例,不是用户点击选中的项目,导致所有任务都加到了这个空实例里
  • renderTasks里错误地直接访问isEmpty方法引用,没加括号调用;同时遍历的是全局taskArr,不是当前项目的任务数组
  • addTaskBtn函数完全没用到选中的selectedProj,反而用了全局空Project,而且调用renderTasks时传参错误

具体修复步骤

  1. 删掉多余的全局变量
    直接移除全局的project和taskArr,这俩不仅没用,还会混淆逻辑,所有操作都基于选中的selectedProj来做。

  2. 修正renderTasks函数

    • 调用isEmpty()(加括号)来判断项目是否为空
    • 遍历当前项目的tasksArray,而非全局taskArr
    • 增加未选中项目的提示,引导用户先选项目
  3. 修正addTaskBtn函数

    • 先检查有没有选中项目,没有就提示用户
    • 用selectedProj来添加任务,而不是全局空Project
    • 添加任务后重新渲染当前选中项目的任务列表
  4. 修复删除按钮的事件逻辑
    原删除按钮的事件参数错误,直接通过闭包获取当前项目即可,还要阻止事件冒泡,避免点击删除时触发父元素的选中事件。

修正后的完整代码

JavaScript部分

//单个项目类
class Project {
    constructor(name) {
        this.name = name;
        this.tasksArr = [];
    }
    get nameOfProject() {
        return this.name;
    }
    get tasksArray() {
        return this.tasksArr;
    }
    isEmpty() {
        return this.tasksArr.length === 0;
    }
    addTasksToProject(name, dueDate) {
        let newTask = new Task(name, dueDate);
        this.tasksArr.push(newTask);
        return newTask;
    }
}
//项目组类
class Projects {
    constructor() {
        this.listOfProjects = [new Project("示例项目")];
    }
    addProjectToList(name) {
        let p = new Project(name);
        this.listOfProjects.push(p);
        return p;
    }
    get allProjects() {
       return this.listOfProjects;
    }
    get numOfProjects() {
        return this.listOfProjects.length;
    }
}

//任务类
class Task {
    constructor(name, dueDate) {
        this.name = name;
        this.dueDate = dueDate;
        this.completed = false;
    }
}

//全局变量
let projects = new Projects();
let projArr = projects.allProjects;
let projectId = 0;
let selectedProj = null;

//渲染任务列表
function renderTasks(currentProj) {
    const taskList = document.getElementById("task-list");
    //未选中项目时的提示
    if (!currentProj) {
        taskList.textContent = "请先选择一个项目来查看或添加任务";
        return;
    }
    if (currentProj.isEmpty()) {
        taskList.textContent = "该项目目前没有任务,请在下方添加任务";
    } else {
        taskList.textContent = "";
        //遍历当前项目的任务数组
        currentProj.tasksArray.forEach(task => {
            const newTaskDiv = document.createElement("div");
            newTaskDiv.textContent = task.name;
            newTaskDiv.classList.add("task-item");
            taskList.appendChild(newTaskDiv);
        });
    }
}

//选中项目事件
function selectProject(e) {
    let currentProj = projArr[e.currentTarget.id];
    selectedProj = currentProj;
    renderTasks(selectedProj);
}

//渲染项目列表
projArr.forEach(renderProjects);
function renderProjects(project) {
  const newProjectDiv = document.createElement("div");
  const dltBtn = document.createElement("button");
  const projectDom = document.getElementById("project-list");
    newProjectDiv.textContent = project.nameOfProject;
    dltBtn.textContent = "删除";
    newProjectDiv.classList.add("project-item");
    newProjectDiv.appendChild(dltBtn);
    projectDom.append(newProjectDiv);
    newProjectDiv.id = projectId;
    //修正删除按钮逻辑
    dltBtn.addEventListener("click", (e) => {
        e.stopPropagation(); //阻止事件冒泡到父元素的选中事件
        const projectIndex = projArr.indexOf(project);
        if (projectIndex !== -1) {
            projArr.splice(projectIndex, 1);
            newProjectDiv.remove();
            resetIds(projectIndex);
            //如果删除的是当前选中项目,清空选中状态
            if (selectedProj === project) {
                selectedProj = null;
                renderTasks(null);
            }
        }
        projectId -= 1;
    });
    newProjectDiv.addEventListener("click", selectProject);
    projectId++;
}

//重置项目DOM的ID
function resetIds(startIndex) {
    for (let i = startIndex; i < projArr.length; i++) {
        const element = document.getElementById(i + 1);
        if (element) {
            element.id = i;
        }
    }
}

//事件监听
const addBtn = document.getElementById("add");
const addTask = document.getElementById("addTask")
addBtn.addEventListener("click", addProjectBtn);
addTask.addEventListener("click", addTaskBtn)

//添加项目按钮逻辑
function addProjectBtn() {
    let projName = prompt("请输入项目名称");
    if (!projName) return; //取消输入则返回
    let pushProj = projects.addProjectToList(projName);
    renderProjects(pushProj);
}

//添加任务按钮逻辑
function addTaskBtn() {
    if (!selectedProj) {
        alert("请先选择一个项目");
        return;
    }
    let taskName = prompt("请输入任务名称");
    if (!taskName) return;
    selectedProj.addTasksToProject(taskName);
    renderTasks(selectedProj);
}

HTML部分

<button id="add">添加项目</button>
<button id="addTask">添加任务</button>

<div class="container"></div>
<div id="project-list" class="project-list"></div>
<div id="task-list"></div>

内容的提问来源于stack exchange,提问作者Roger Lopez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 19:17:11