模板显示<object Object>,但是在可观察到的异步管道中没有错误

我有待办事项(id,title,complete)

TodosCompenent / index.ts

import {Component, OnInit, ChangeDetectionStrategy, ChangeDetectorRef} from '@angular/core';
import {Todo, ITodo} from '../../../todo/todo';
import {TodoDataService} from '../../Services/API/todo-data.service';
import {APIService} from '../../Services/API/APIServices';
import {AuthService} from '../../Services/AuthService/auth.service';
import {Router} from '@angular/router';
import {Observable} from 'rxjs';
import {select, Store} from '@ngrx/store';
import {TodoState} from '../../store/Reducer/todo.reducers';
import {getTodos} from '../../store/selector/todo.selector';
import {getTodoRequest} from '../../store/Actions/todo.action';

@Component({
  selector: 'app-todos',
  templateUrl: './index.html',
  styleUrls: ['./index.css'],
  providers: [TodoDataService, APIService],
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class TodosComponent implements OnInit {


 constructor(private todoDataService: TodoDataService,
             private auth: AuthService,
             private route: Router,
             private ref: ChangeDetectorRef,
             private store: Store<TodoState>
  ) {}
  todo$ = this.store.pipe(select(getTodos));
  public ngOnInit() {
   // this.store.dispatch(getTodoRequest());
  }
  onAddToDo(todo) {
    // this.todoDataService.addTodo(todo).subscribe((newTodo) => {
    //   this.todos = this.todos.concat(newTodo);
    //   // this.fetchTodo();
    // });
  }
  // onToggleTodoComplete(todo) {
  //   this.todoDataService.onToggleComplete(todo).subscribe((updatedTodo) => {
  //     todo = updatedTodo;
  //     // this.fetchTodo();
  //   });
  // }
  // onRemoveTodo(todo) {
  //   this.todoDataService.deleteTodo(todo.id).subscribe((_) => {
  //     this.todos.filter((t) => t.id !== todo.id);
  //     // this.fetchTodo();
  //   });
  // }
  // fetchTodo() {
  //   this.todoDataService.getTodos().subscribe((todos) => {
  //     this.todos = todos;
  //   });
  // }
  signOut() {
    this.auth.signOut();
    this.route.navigate(['/index']);
  }

}

这是一个使用异步管道但无法正常工作的模板,仍然显示[object Object]

TodosCompenent / index.html

  <app-todo-list-header (add)="onAddToDo($event)"></app-todo-list-header>
  <div *ngIf="(todo$ | async) as todos">
  <app-todo-list
    [todos]="todos"
    (toggleComplete)="onToggleTodoComplete($event)"
    (remove)="onRemoveTodo($event)"
  ></app-todo-list>
  <app-todo-list-footer [todos]="todo$ | async"></app-todo-list-footer>
  <div fxLayoutAlign="center center" >
    <button mat-flat-button color="primary" (click)="signOut()">Logout</button>
  </div>
  </div>
</section>

我使用应用程序状态选择待办事项。

todo.seletor.ts

import {createFeatureSelector, createSelector} from '@ngrx/store';
import {TodoState, selectAll, selectTotal} from '../Reducer/todo.reducers';
import {ITodo} from '../../../todo/todo';

export  interface AppState {
  todos: ITodo[];
}
export const selectorName = 'todos';
export const getTodoState = createFeatureSelector<TodoState>(selectorName);
// export const getTodoState = createSelector(todoFeatureSelector, state => state.entities);

export const todoCount = selectTotal;
// @ts-ignore
export const getTodos = createSelector(getTodoState, (state: AppState) => state.todos );
// export const getTodos = createSelector(getTodoState, selectAll );

// export const getTodoCount = createSelector(getTodoState, todoCount);

我在减速器状态下使用ngrx / enntity。

待办事项

import { ITodo, Todo } from '../../../todo/todo';
import { EntityAdapter, EntityState } from '@ngrx/entity/src/models';
import { createEntityAdapter } from '@ngrx/entity';
import {todoActions} from '../Actions/todo.action';
import {Action, createReducer, on, State} from '@ngrx/store';

export interface TodoState extends EntityState<ITodo> {
  error: string;
  message: string;
}

export const adapter: EntityAdapter<Todo> = createEntityAdapter<ITodo>();

export const initialTodoState: TodoState = adapter.getInitialState({
  error: null,
  message: null
});

export const todoReducer = createReducer(
  initialTodoState,
  on(todoActions.getTodoRequest, (state, action) => {
      return adapter.removeAll({...state, error: null});
    }
  ),
  on(todoActions.getTodoFailure, (state, action) => {
    return {...state, error: action.payload};
  }),
  on(todoActions.getTodoSuccess, (state, action) => {
    return adapter.setAll(action.todo, {...state});
  }),
  on(todoActions.addTodoSuccess, (state, action) => {
    return adapter.addOne(action.payload, {...state, error: null});
  }),
  on(todoActions.updateTodoRequest, (state, action) => {
    return adapter.updateOne(action.update, {...state, error: null});
  }),
  on(todoActions.updateTodoSuccess, (state, action) => {
    return adapter.addOne(action.payload, {...state, error: null});
  }),
  on(todoActions.updateTodoFailure, (state, action) => ({...state, error: action.payload})
  ),
  on(todoActions.deleteTodoRequest, (state, action) => {
      return adapter.removeOne(action.todoID, {...state, error: null, message: null});
    }
  ),
  on(todoActions.deleteTodoSuccess, (state, action) => {
    return {...state, error: null, message: action.message};
  }),
  on(todoActions.deleteTodoFailure, (state, action) => {
    return {...state, error: action.payload, message: null};
  })
);

export const {
  selectAll,
  selectIds,
  selectTotal,
  selectEntities
} = adapter.getSelectors();

我已经尝试过了,但是这些都不适合我。我一直在努力解决这个问题。

<div *ngIf="user$ | async; let user">
  <h3> {{user.name}}
</div>
<div *ngIf="(primitive$ | async) || ' '; let primitive">
  <h3> {{primitive}}
</div>
<div *ngIf="(user$ | async) || {}; let user">
  <h3> {{user?.name}}
</div>

TodoListComponent / index.ts

import {ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Input, Output} from '@angular/core';
import {ITodo, Todo} from '../../../todo/todo';
import {select, Store} from '@ngrx/store';
import {TodoState} from '../../store/Reducer/todo.reducers';

@Component({
  selector: 'app-todo-list',
  templateUrl: './index.html',
  styleUrls: ['./todoList.component.css'],
})
export class TodoListComponent {
  @Input()
  todos: ITodo[];

  @Output()
  remove: EventEmitter<Todo> = new EventEmitter();

  @Output()
  toggleComplete: EventEmitter<Todo> = new EventEmitter();

  constructor(
    private store: Store<TodoState>
  ) {}
// todoCount = this.store.pipe(select(getTodoCount));
  onToggleTodoComplete(todo: Todo) {
    this.toggleComplete.emit(todo);

  }
  onRemoveTodo(todo: Todo) {
    this.remove.emit(todo);

  }
}

TodoListComponent / index.html

  <div *ngIf="!(todoCount | async)" class="view" style=";">
    No Todo at the moment
  </div>

<section class="main" *ngIf="(todoCount | async) > 0">
  <ul class="todo-list">
    <li *ngFor="let todo of todos" [class.completed]="todo.complete">
      <app-todo-list-item
        [todo]="todo"
        (toggleComplete)="onToggleTodoComplete($event)"
        (remove)="onRemoveTodo($event)"
      ></app-todo-list-item>
    </li>
  </ul>
</section>

TodoListItemComponents / index.html

<div class="view">
  <div fxLayout="row" fxLayoutAlign="center center">
    <div fxFlex="50%">
      <mat-checkbox
        (click)="onToggleTodoComplete(todo)"
        [checked]="todo.complete"
        [style]="todo.complete?'text-decoration: line-through':''"
        color="primary"
        >{{todo?.title}}</mat-checkbox
      >
    </div>
    <div fxFlex="20%" style="padding: 5px;">
      <button
        mat-flat-button
        style="
          background-color: #dc3545;
          border-color: #dc3545;
          width: 20px;
          min-width: 36px;
        "
        class="destroy"
        (click)="onRemoveTodo(todo)"
      >
        <span style="color: white;">
          X
        </span>
      </button>
    </div>
    <div fxFlex="20%" style="padding: 5px;">
      <button
        mat-flat-button
        style="
          background-color: #dc3545;
          border-color: #dc3545;
          width: 20px;
          min-width: 36px;
        "
        class="destroy"
        (click)="editTodo(todo.id)"
      >
        <app-edit-icon style="position:relative;right:10px;top:4px" ></app-edit-icon>
      </button>
    </div>
  </div>
</div>

TodoListItemComponents / index.ts


import {
  ChangeDetectionStrategy, ChangeDetectorRef,
  Component,
  EventEmitter,
  Input,
  OnChanges,
  OnInit,
  Output
} from '@angular/core';
import {ITodo, Todo} from '../../../../../todo/todo';
import { TodoDataService } from '../../../../Services/API/todo-data.service';
import { UpdateTodoModalComponent } from '../update-todo-modal/update-todo-modal.component';
import { BsModalService, BsModalRef } from 'ngx-bootstrap/modal';

@Component({
  selector: 'app-todo-list-item',
  templateUrl: './index.html',
  styleUrls: ['./index.css'],
  changeDetection: ChangeDetectionStrategy.Default

})
export class TodoListItemComponent implements OnInit {
  bsModalRef: BsModalRef;
  @Input()
  todo: ITodo;
  todos: ITodo[];

  @Output()
  remove: EventEmitter<Todo> = new EventEmitter();

  @Output()
  toggleComplete: EventEmitter<Todo> = new EventEmitter();

  constructor(
    private todoDataService: TodoDataService,
    private bsModalService: BsModalService,
    private ref: ChangeDetectorRef
  ) {
  }

  ngOnInit() {
    this.getTodoList();
  }

  editTodo(todoId: number) {
    const initialState = {
      data: this.todos,
      id: todoId,
      ignoreBackdropClick: true,
      animated: true,
      keyboard: true,
    };
    this.bsModalRef = this.bsModalService.show(UpdateTodoModalComponent, {
      initialState,
    });
    this.bsModalRef.content.event.subscribe((result) => {
      if (result === 'Ok') {
        // this.getTodoList();
      }
    });
  }
  getTodoList() {
      this.todoDataService.getTodos().subscribe((todos) => {
        this.todos = todos;
        this.ref.detectChanges();
      });
  }
  onToggleTodoComplete(todo: Todo) {
    this.toggleComplete.emit(todo);
  }
  onRemoveTodo(todo: Todo) {
    this.remove.emit(todo);
  }
}