实体未在@ ngrx / data中更新

时间:2020-02-27 01:59:57

标签: angular ngrx angular-ngrx-data

我正在尝试通过创建简单的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,但实体仍显示旧数据。不知道我在做什么错,

请帮助

1 个答案:

答案 0 :(得分:2)

欢迎使用@ 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中的代码。

如果要实现 Load More (加载更多)功能,则应对其他事件(例如滚动或单击按钮)做出反应,然后再次调用loadMore

您的entities$loaded$之类的可观察对象仅仅是数据管道,在发出新值时您不应调度动作。 如果确实需要,最好写一个@ngrx/effect,就是这样做的。

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

例如,可以:

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

希望我的答案很明确,将对您有所帮助。