4

我正在尝试通过创建简单的 TODO 应用程序来学习 @ngrx/data

我创建了简单的 ToDoDataService 来覆盖默认 HTTP

@Injectable()
export class TodosDataService extends DefaultDataService<Todo> {

  constructor(httpClient: HttpClient, httpUrlGenerator: HttpUrlGenerator) {
    super('Todo', httpClient, httpUrlGenerator);
  }

  getAll(): Observable<Array<Todo>> {
    console.log('asfsfsfsf')
    return this.http.get('https://jsonplaceholder.typicode.com/todos')
      .pipe(
        map((res: any) => res)
      );
  }

  getWithQuery(query): Observable<Array<any>> {
    console.log('asfsfsfsf', query);
    return this.http.get(`https://jsonplaceholder.typicode.com/todos?${query}`)
      .pipe(
        map((res: any) => res)
      );
  }    
}

在路由解析器中,我正在这样做

@Injectable()
export class TodosResolver implements Resolve<boolean> {

  constructor(private todoService: TodoEntityService) {

  }
  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean>  {

    return this.todoService.loaded$
      .pipe(
        tap(loaded => {
          if (!loaded) {
            this.todoService.getAll();
          }
        }),
        filter(loaded => !!loaded),
        first()
      );
  }

}

这工作正常,商店/实体已更新

但在我的组件中,我正在这样做

export class HomeComponent implements OnInit {

  loading$: Observable<boolean>;

  todos$: Observable<Todo[]>;

  constructor(
    private todoService: TodoEntityService
  ) { }

  ngOnInit() {
    console.log('dsdf');
    this.todos$ = this.todoService.entities$
      .pipe(
        tap(todos => {
          console.log(todos);
          this.loadMore();
          console.log(todos);

        }),
        map((todos: any) => todos),
        first()
      );
  }

  loadMore() {
    this.todoService.getWithQuery('_start=20&_limit=5');
  }

}

这里 API 正在调用,但实体仍在显示旧数据。不知道我做错了什么,

请帮忙

4

1 回答 1

3

欢迎来到@ngrx/data。

我建议你查看里面的代码片段ngOnInit。在这里,您调用loadMore方法,这意味着每次更新集合时都会发出一个新的 Http 请求。

您的代码应如下所示:

ngOnInit() {
  // keep a local reference to observable of entities
  this.todos$ = this.todoService.entities$;

  // request a first load on view init
  this.loadMore();
}

这样一来,里面的代码TodosResolver就不是真的需要了。

如果您想实现加载更多功能,您应该对另一个事件(如滚动或单击按钮)做出反应,然后再次调用loadMore.

你的 observables 像entities$或者loaded$只是数据管道,当新值发出时你不应该调度动作。如果真的需要,宁愿写一个@ngrx/effect,它已经完成了。

如果您想更改数据或其格式,您可以使用Observable管道,但不能调用新操作。

例如,这没关系:

this.todos$ = this.todoService.entities$.pipe(
  map(entities => entities.map(entity => ({
    ...entity,
    authorName: entity.authorFirstname + ' ' + entity.authorLastName
  })));
);

希望我的回答很清楚,对你有一点帮助。

于 2020-02-28T05:37:40.700 回答