ngrx:在加载页面之前从商店获取价值

时间:2019-08-15 11:28:38

标签: angular ngrx ngrx-store

我有页面组件,其中正在显示ngrx/store中的一些数据:

// profile.ts
user$: User = this.store.select('user')
// profile.html
...

<div *ngIf="user$ | async; let user">
  <div>{{user.id}}</div>  
  <div>{{user.email}}</div>
</div>

这有效,但是我不喜欢它最初加载的页面没有数据,然后在1秒钟后从user$添加此数据。我知道这是应该的-因为我使用的是异步管道,但是我想更改它。

我有什么选择?我可以以某种方式从商店中预加载此user选择,以将其包含在所有组件中,这样我就不需要每次都从商店中获取它们,因此,我从中获取一些数据的所有页面加载后从商店“忽悠”?

1 个答案:

答案 0 :(得分:0)

最简单的不获取数据(如果已经在商店中)的方法是在效果内部-我自己Start using ngrx/effects for this

@Effect()
getOrder = this.actions.pipe(
  ofType<GetOrder>(ActionTypes.GetOrder),
  withLatestFrom(action =>
    of(action).pipe(
      this.store.pipe(select(getOrders))
    )
  ),
  filter(([{payload}, orders]) => !!orders[payload.orderId])
  mergeMap([{payload}] => {
    ...
  })
)

但是,我认为您正在寻找的是Angular路由器防护,可在您将数据存储在商店中后提取数据并加载页面。 有关更多信息,请参见Todd Motto的Preloading ngrx store with Route Guards

@Injectable()
export class CoursesGuard implements CanActivate {
  constructor(private store: Store<CoursesState>) {}

  getFromStoreOrAPI(): Observable<any> {
    return this.store
      .select(getCoursesState)
      .do((data: any) => {
        if (!data.courses.length) {
          this.store.dispatch(new Courses.CoursesGet());
        }
      })
      .filter((data: any) => data.courses.length)
      .take(1);
  }

  canActivate(): Observable<boolean> {
    return this.getFromStoreOrAPI()
      .switchMap(() => of(true))
      .catch(() => of(false));
  }
}

对于(最好的?)UX,您还可以使用鬼元素-Thomas Burleson的Great User Experiences with Ghost Elements