【发布时间】:2020-08-08 13:18:55
【问题描述】:
我有一个带有全局数据服务的示例 Angular 应用程序,我试图通过过滤它在组件的多个实例之间共享它。这是我更大应用程序的原型,但我在两者中都遇到了同样的问题。我尝试使用管道过滤器,但收到错误消息。现在,我想要一些关于在这种情况下的最佳实践的指导,因为这是我第一次尝试这样做。如果是管道过滤,那么我需要有关错误消息的帮助。
我的示例使用返回 ToDo 项的测试 API。我想将该服务用于在一个实例中显示已完成项目而在另一个实例中显示未完成项目的组件。也有 userId 过滤只是因为我觉得我需要另一个元素。
服务:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, BehaviorSubject } from 'rxjs';
export interface Todo {
userId: number;
id: number;
title: string;
completed: boolean;
}
@Injectable({
providedIn: 'root'
})
export class TodosService {
private _todos$: BehaviorSubject<Todo[]> = new BehaviorSubject(null);
constructor(private http: HttpClient) { }
// Public Methods
get todos() {
return this._todos$.asObservable();
}
loadData() {
this._listTodos()
.subscribe(
res => {
this._todos$.next(res);
},
err => console.log('Error receiving todo items.', err)
);
}
addTodo(todo: Todo) {
this._addTodo(todo).subscribe( item => {
const d = this._todos$.getValue();
d.push(item);
this._todos$.next(d);
});
}
// Private methods
_listTodos(): Observable<Todo[]> {
return this.http.get<Todo[]>('https://jsonplaceholder.typicode.com/todos');
}
_addTodo(todo: Todo): Observable<Todo> {
return this.http.post<Todo>('https://jsonplaceholder.typicode.com/todos', todo);
}
}
组件:
<div>
<button (click)="addTodo()">Add Todo</button>
</div>
<ng-container *ngIf="(todosService.todos | todoFilter$: complete: userId | async) as todos">
<h1>Completed: {{ complete }} UserId: {{ userId }} </h1>
<ul>
<li *ngFor="let todo of todos">
{{ todo.id}} - {{ todo.userId }} - {{ todo.title }}
</li>
</ul>
</ng-container>
import { Component, OnInit, Input, OnChanges } from '@angular/core';
import { Todo, TodosService} from '../../services/todos.service';
@Component({
selector: 'app-todo',
templateUrl: './todo.component.html',
styleUrls: ['./todo.component.css']
})
export class TodoComponent implements OnChanges {
@Input() complete: false;
@Input() userId: number = null;
constructor(private todosService: TodosService) { }
ngOnChanges() {
this.load();
}
async load() {
await this.todosService.loadData();
}
addTodo() {
const t: Todo = {
id: 999,
userId: this.userId,
title: 'Css Add',
completed: this.complete
};
this.todosService.addTodo(t);
}
}
管道过滤器(抛出错误:无法读取 null 的属性“过滤器”。kws 显然为 null,但我不确定为什么填充 items$?):
import { Pipe, PipeTransform } from '@angular/core';
import { Todo } from '../services/todos.service';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
@Pipe({
name: 'todoFilter$'
})
export class TodoFilterPipe implements PipeTransform {
transform(items$: Observable<Todo[]>, complete: boolean, userId: number): any {
if (!items$ || items$ == null || items$ === undefined) { return null; }
return items$.pipe(map(
kws => kws.filter(kw => (kw.completed === complete && (!userId || kw.userId === userId))
))
);
}
}
应用组件示例页面:
<app-todo complete="false"></app-todo>
<app-todo complete="true" userId="1"></app-todo>
请告诉我最好的方法是什么?
【问题讨论】:
标签: angular filter service observable