Ember任务管理应用 #

一、项目概述 #

1.1 功能需求 #

  • 添加任务
  • 完成任务
  • 删除任务
  • 过滤显示
  • 本地存储

二、数据模型 #

2.1 Todo模型 #

javascript
// app/models/todo.js
import Model, { attr } from '@ember-data/model';

export default class TodoModel extends Model {
  @attr('string') title;
  @attr('boolean', { defaultValue: false }) completed;
  @attr('date') createdAt;
}

三、服务实现 #

3.1 Todo服务 #

javascript
// app/services/todos.js
import Service from '@ember/service';
import { tracked } from '@glimmer/tracking';
import { inject as service } from '@ember/service';

export default class TodosService extends Service {
  @service store;

  @tracked filter = 'all';

  async addTodo(title) {
    const todo = this.store.createRecord('todo', {
      title,
      completed: false,
      createdAt: new Date(),
    });
    await todo.save();
  }

  async toggleTodo(todo) {
    todo.completed = !todo.completed;
    await todo.save();
  }

  async deleteTodo(todo) {
    await todo.destroyRecord();
  }

  get allTodos() {
    return this.store.peekAll('todo');
  }

  get filteredTodos() {
    const todos = this.allTodos;

    switch (this.filter) {
      case 'active':
        return todos.filterBy('completed', false);
      case 'completed':
        return todos.filterBy('completed', true);
      default:
        return todos;
    }
  }

  get remainingCount() {
    return this.allTodos.filterBy('completed', false).length;
  }
}

四、组件实现 #

4.1 TodoInput组件 #

javascript
// app/components/todo-input.js
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';

export default class TodoInputComponent extends Component {
  @service todos;
  @tracked newTitle = '';

  @action
  updateTitle(event) {
    this.newTitle = event.target.value;
  }

  @action
  async addTodo(event) {
    event.preventDefault();

    if (this.newTitle.trim()) {
      await this.todos.addTodo(this.newTitle);
      this.newTitle = '';
    }
  }
}

4.2 TodoItem组件 #

javascript
// app/components/todo-item.js
import Component from '@glimmer/component';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';

export default class TodoItemComponent extends Component {
  @service todos;

  @action
  async toggle() {
    await this.todos.toggleTodo(this.args.todo);
  }

  @action
  async delete() {
    await this.todos.deleteTodo(this.args.todo);
  }
}

五、总结 #

Todo应用要点:

功能 实现
状态管理 Service
数据持久化 Ember Data
组件通信 @args/@action

通过Todo应用学习Ember核心概念。

最后更新:2026-03-28