我正在尝试编写一个简单的待办事项应用程序以学习Angular6。在我的应用程序中,待办事项可以完成或未完成,我想在页脚组件中显示未完成的待办事项数量。
我有一个待办事项组件,显示待办事项列表:
todos.component.ts
export class TodosComponent implements OnInit {
todos: Todo[];
constructor(private todoService: TodoService) {
this.todos = todoService.GetAll();
}
ngOnInit() {}
ToggleTodoCompleted(id: number): void{
this.todoService.Toggle(id);
}
}
要添加待办事项的另一个组件:
todo-add.component.ts
export class TodoAddComponent implements OnInit {
constructor(private todoService: TodoService) { }
ngOnInit() {}
AddTodo(todoTitle){
let todo = new Todo();
todo.title = todoTitle;
this.todoService.Add(todo);
}
}
一个页脚组件,我使用一个不纯管道来显示其中未完成的待办事项的数量:
footer.component.ts
export class FooterComponent implements OnInit {
todos: Todo[] = [];
constructor(private todoService: TodoService) {
this.todos = todoService.GetAll();
}
ngOnInit() {}
}
uncompleted-todos.pipe.ts
@Pipe({
name: 'uncompletedTodos',
pure: false
})
export class UncompletedTodosPipe implements PipeTransform {
transform(todos: Todo[]): any {
return todos.filter(t=>t.completed===false);
}
}
footer.component.html
{{(todos|uncompletedTodos).length}} items left
和简单的服务:
todo.service.ts
export class TodoService {
private todos: Todo[] = [];
GetAll(): Todo[]{
return this.todos;
}
Add(todo: Todo): void{
todo.id = this.todos.length + 1;
todo.completed = false;
this.todos.push(todo);
}
Toggle(id: number): void{
let todo = this.todos.find(t => t.id === id);
todo.completed = !todo.completed;
}
}
但是我在Angular文档中读到,不纯管道会导致性能问题。那么,另一种选择是什么呢?没有这种不纯净的管道,如何编写代码?
答案 0 :(得分:1)
这是right in the documentation的解释:
Angular不提供用于过滤或排序列表的管道[...]这不是疏忽。 Angular不提供此类管道,因为它们性能不佳并阻止了积极的缩小[...] Angular团队和许多经验丰富的Angular开发人员强烈建议将过滤和排序逻辑移入组件本身
这意味着您应该摆脱管道,并将逻辑直接放入组件中。
例如EDIT ,以将逻辑放入功能本身中:
export class TodoService {
private todos: Todo[] = [];
GetAll(): Todo[]{
return this.todos;
}
GetUncompleted() {
return this.todos.filter(td => !td.completed);
}
...
编辑2 您的问题来自于在组件启动时仅分配一次待办事项的值。
这意味着将项目添加到待办事项列表时,您看不到更改,因为您没有更新值。
为此,有两种解决方案:第一种是使用吸气剂。
字母是特殊的函数,它们在被调用时都会更新其值。使用非常简单。例如,在您的todo.component
中,它将给出:
get todos() { return this.todoService.getAll(); }
您现在可以通过
在模板中使用它*ngFor="let todo of todos"
这将被更新。
Here is a stackblitz to show you how getters work
第二种解决方案是使用RxJS。这是一个事件解决方案:当列表更新时,您必须触发一个事件。由于此解决方案比较困难,因此我制作了this stackblitz来帮助您理解它。
基本上发生的是,每当您的列表更新时,您的组件都会收到一个事件,告诉他们必须更新待办事项列表。