Angular 6 中不纯管道的替代品?
Alternative for impure pipes in Angular 6?
我正在尝试编写一个简单的待办事项应用程序来学习Angular 6. 在我的应用程序中,待办事项可以完成或未完成,我想在页脚组件中显示未完成待办事项的数量。
我有一个显示待办事项列表的待办事项组件:
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() {}
}
未完成-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 文档中读到,不纯的管道会导致性能问题。那么替代方案是什么?如果没有这个不纯的管道,我怎么能写我的代码?
这是解释right in the documentation:
Angular doesn't provide pipes for filtering or sorting lists [...] This isn't an oversight. Angular doesn't offer such pipes because they perform poorly and prevent aggressive minification [...] The Angular team and many experienced Angular developers strongly recommend moving filtering and sorting logic into the component itself
这意味着你应该摆脱你的管道,并将逻辑直接放在你的组件中。
EDIT 例如,将逻辑放入功能本身:
export class TodoService {
private todos: Todo[] = [];
GetAll(): Todo[]{
return this.todos;
}
GetUncompleted() {
return this.todos.filter(td => !td.completed);
}
...
编辑 2 你的问题来自于你只在组件启动时分配一次待办事项的值。
这意味着当您将项目添加到待办事项列表时,您看不到更改,因为您没有更新值。
对此,有两种解决方案:第一种是使用吸气剂。
Getter 是一种特殊的函数,只要被调用就会更新它们的值。使用起来非常简单。例如,在您的 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来帮助你理解它。
基本上发生的事情是,每当您的列表更新时,您的组件都会收到一个事件,告诉它们必须更新待办事项列表。
我正在尝试编写一个简单的待办事项应用程序来学习Angular 6. 在我的应用程序中,待办事项可以完成或未完成,我想在页脚组件中显示未完成待办事项的数量。
我有一个显示待办事项列表的待办事项组件:
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() {}
}
未完成-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 文档中读到,不纯的管道会导致性能问题。那么替代方案是什么?如果没有这个不纯的管道,我怎么能写我的代码?
这是解释right in the documentation:
Angular doesn't provide pipes for filtering or sorting lists [...] This isn't an oversight. Angular doesn't offer such pipes because they perform poorly and prevent aggressive minification [...] The Angular team and many experienced Angular developers strongly recommend moving filtering and sorting logic into the component itself
这意味着你应该摆脱你的管道,并将逻辑直接放在你的组件中。
EDIT 例如,将逻辑放入功能本身:
export class TodoService {
private todos: Todo[] = [];
GetAll(): Todo[]{
return this.todos;
}
GetUncompleted() {
return this.todos.filter(td => !td.completed);
}
...
编辑 2 你的问题来自于你只在组件启动时分配一次待办事项的值。
这意味着当您将项目添加到待办事项列表时,您看不到更改,因为您没有更新值。
对此,有两种解决方案:第一种是使用吸气剂。
Getter 是一种特殊的函数,只要被调用就会更新它们的值。使用起来非常简单。例如,在您的 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来帮助你理解它。
基本上发生的事情是,每当您的列表更新时,您的组件都会收到一个事件,告诉它们必须更新待办事项列表。