Для моего приложения todo я следил за этим сообщением в блоге, чтобы реализовать сервис для обмена данными с моими компонентами: 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>
Насколько я понял, я должен использовать только методы readonly, такие как todos$
или completedToDos$
для отображения данных, поскольку они не могут изменять данные.Чтобы иметь возможность изменять данные, у меня есть такие методы, как getToDos
и т. Д.
Ну, я думал, что все отлично, и я понял это, ну, по-видимому, я не сделал.Когда я пытаюсь получить все элементы todo в 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">
Где я ошибся или что я не понял?
Спасибо за вашу помощь!