任务管理应用如 Todoist 或 Trello,需要处理任务状态、列表管理、用户协作等复杂逻辑。easy-model 的领域驱动设计能清晰组织这些功能模块。本文通过实际用例展示 easy-model 在任务管理中的应用。
任务模型设计
任务是核心领域实体。我们创建 TaskModel 封装任务逻辑:
typescript
import { useModel } from "easy-model";
class TaskModel {
task = {
id: "",
title: "",
description: "",
completed: false,
priority: "medium" as "low" | "medium" | "high",
dueDate: null as Date | null
};
constructor(initialTask: typeof this.task) {
this.task = initialTask;
}
toggleComplete() {
this.task.completed = !this.task.completed;
}
updatePriority(newPriority: typeof this.task.priority) {
this.task.priority = newPriority;
}
isOverdue() {
return this.task.dueDate && new Date() > this.task.dueDate && !this.task.completed;
}
}
function TaskItem({ taskId }: { taskId: string }) {
const params = useMemo(() => [{
id: taskId,
title: "完成项目报告",
description: "撰写Q1季度报告",
completed: false,
priority: "high",
dueDate: new Date("2024-03-20")
}])
const taskModel = useModel(TaskModel, params);
return (
<div>
<h4>{taskModel.task.title}</h4>
<p>{taskModel.task.description}</p>
<p>优先级: {taskModel.task.priority}</p>
<p>状态: {taskModel.task.completed ? "已完成" : "进行中"}</p>
{taskModel.isOverdue() && <p style={{color: 'red'}}>已逾期</p>}
<button onClick={() => taskModel.toggleComplete()}>
{taskModel.task.completed ? "标记未完成" : "标记完成"}
</button>
</div>
);
}
模型封装任务业务规则,如逾期判断、状态切换等。
任务列表管理
任务列表需要跨组件共享状态:
typescript
import { useModel } from "easy-model";
class TaskListModel {
tasks: TaskModel[] = [];
listId: string;
constructor(listId: string) {
this.listId = listId;
}
addTask(task: InstanceType<typeof TaskModel>) {
this.tasks.push(task);
}
getCompletedCount() {
return this.tasks.filter(t => t.task.completed).length;
}
getPendingTasks() {
return this.tasks.filter(t => !t.task.completed);
}
}
function TaskList({ listId }: { listId: string }) {
const taskList = useModel(TaskListModel, [listId]);
return (
<div>
<h3>任务列表 ({taskList.tasks.length} 个任务)</h3>
<p>已完成: {taskList.getCompletedCount()}</p>
<p>待完成: {taskList.getPendingTasks().length}</p>
{taskList.tasks.map(task => (
<TaskItem key={task.task.id} taskId={task.task.id} />
))}
</div>
);
}
useModel 确保列表状态在组件间共享。
协作功能
多用户协作涉及异步操作:
typescript
import { loader, useLoader, useModel } from "easy-model";
class CollaborationModel {
collaborators: string[] = [];
projectId: string;
constructor(projectId: string) {
this.projectId = projectId;
}
@loader.load(true)
async inviteUser(email: string) {
// 模拟API
await new Promise(resolve => setTimeout(resolve, 1500));
this.collaborators.push(email);
}
}
function InviteForm({ projectId }: { projectId: string }) {
const collabModel = useModel(CollaborationModel, [projectId]);
const { isLoading } = useLoader();
return (
<form onSubmit={(e) => {
e.preventDefault();
const email = (e.target as any).email.value;
collabModel.inviteUser(email);
}}>
<input name="email" placeholder="用户邮箱" />
<button type="submit" disabled={isLoading(collabModel.inviteUser)}>
{isLoading(collabModel.inviteUser) ? "邀请中..." : "邀请用户"}
</button>
</form>
);
}
异步邀请处理,加载状态自动管理。
可测试性保证
模型类支持全面测试:
typescript
describe("TaskModel", () => {
it("should toggle completion", () => {
const model = new TaskModel({
id: "1",
title: "Test",
description: "",
completed: false,
priority: "medium",
dueDate: null,
});
model.toggleComplete();
expect(model.task.completed).toBe(true);
});
it("should detect overdue", () => {
const pastDate = new Date("2020-01-01");
const model = new TaskModel({
id: "1",
title: "Test",
description: "",
completed: false,
priority: "medium",
dueDate: pastDate,
});
expect(model.isOverdue()).toBe(true);
});
});
测试覆盖业务逻辑,确保功能正确。
总结
easy-model 在任务管理应用中展现出色:清晰的领域建模、状态共享、异步处理。结合测试驱动开发,提升应用质量。体验 easy-model,让任务管理更高效!
项目地址:GitHub