对于我的待办事项应用程序,我已经关注了此博客文章,以实现将数据共享到我的组件的服务:https://dev.to/avatsaev/simple-state-management-in-angular-with-only-services-and-rxjs-41p8
它目前正在工作,但没有达到预期的目的(至少据我所知)。
服务:
@Injectable({providedIn: 'root'})
export class TodoListService {
showCompleted = false;
@Input() toDoData = {taskName: '', extraNote: '', taskCompleted: false, dueDate: Date};
constructor(private todoService: TodoService) {
this.getToDos();
}
private readonly todoListSource = new BehaviorSubject<ToDo[]>([]);
readonly todos$ = this.todoListSource.asObservable().pipe(
shareReplay(1)
);
readonly completedToDos$ = this.todos$.pipe(
shareReplay(1),
map(todos => this.todos.filter(todo => todo.taskCompleted))
);
get todos(): ToDo[] {
return this.todoListSource.getValue();
}
set todos(val: ToDo[]) {
this.todoListSource.next(val);
}
getToDos() {
this.todoService.getToDos()
.subscribe((data: []) => {
console.log('TodoModel List get Todos Service: ', data);
this.todos = data;
});
}
addToDo() {
this.todoService.addToDo(this.toDoData)
.subscribe((result) => {
/*console.log(result);*/
});
}
deleteToDo(id) {
this.todoService.deleteToDo(id)
.subscribe(res => {
this.getToDos();
}, (err) => {
console.log(err);
}
);
}
completed(id, todo) {
todo.taskCompleted = !todo.taskCompleted;
this.todoService.updateToDo(id, todo)
.subscribe(res => {
this.getToDos();
}, (err) => {
console.log(err);
});
}
}
HTML:
<mat-card class="example-card" *ngFor="let todo of todoListService.todos$">
<mat-card-header>
<div mat-card-avatar>
<mat-icon [ngClass]="todo.taskCompleted ? 'green' : 'red' ">thumb_up</mat-icon>
</div>
<mat-card-title>{{todo.taskName}}</mat-card-title>
<mat-card-subtitle>
<mat-icon style="font-size: 15px">calendar_today</mat-icon>
{{todo.dueDate | date: 'dd.MM.yyyy'}}</mat-card-subtitle>
</mat-card-header>
<mat-card-content>
<p>
{{todo.extraNote}}
</p>
</mat-card-content>
<mat-card-actions align="center">
<button mat-button (click)="todoListService.completed(todo.id, todo)">
<mat-icon *ngIf="!todo.taskCompleted">done</mat-icon>
<mat-icon *ngIf="todo.taskCompleted">close</mat-icon>
</button>
<button mat-button (click)="openDialog(todo)">
<mat-icon>edit</mat-icon>
</button>
<button mat-button (click)="todoListService.deleteToDo(todo.id)">
<mat-icon>delete</mat-icon>
</button>
</mat-card-actions>
</mat-card>
据我了解,我应该仅使用todos$
或completedToDos$
之类的只读方法来显示数据,因为它们无法修改数据。为了能够修改数据,我使用了getToDos
等方法。
好吧,我认为一切都很好,并且我理解了,很显然我没有。当我尝试获取html中的所有待办事项时,出现此错误:
ERROR Error: Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays.
at NgForOf.push../node_modules/@angular/common/fesm5/common.js.NgForOf.ngDoCheck
所以它不会返回我期望的数组。
如果我更改*ngFor
,它可以正常工作,但据我所知,应该怎么用。
<mat-card class="example-card" *ngFor="let todo of todoListService.todos">
我在哪里出错了,或者我不了解什么?
感谢您的帮助!