Отправка действия хранилища ngrx в преобразователе маршрутов

В настоящее время у меня есть компонент-контейнер (с отслеживанием состояния), который отправляет действия select и get на основе параметра маршрута (id) в методе ngOnInit. Смысл этих действий в том, чтобы данные и выбранный id были в моем магазине.

Мне любопытно, было бы правильно отправлять эти действия в резолвер?

Спасибо за ответы.

Мой компонент:

@Component({
  selector: 'app-container',
  templateUrl: './container.component.html',
  styleUrls: ['./container.component.css']
})
export class ContainerComponent implements OnInit, OnDestroy {

  private componetDestroyed$ = new Subject();

  constructor(private store: Store<fromRoot.State>, private route: ActivatedRoute) { }

  ngOnInit() {
    this.route.params
      .filter(params => params['id'])
      .map(params => params['id'])
      .takeUntil(this.componetDestroyed$)
      .subscribe(id => {
        this.store.dispatch(new GetAction(id));
        this.store.dispatch(new SelectAction(id));
      });
  }

  ngOnDestroy() {
    this.componetDestroyed$.next();
    this.componetDestroyed$.unsubscribe();
  }   
}

Мои маршруты:

[{
  path: ':id',
  component: ContainerComponent
}]

Решателем будет:

@Injectable()
class MyResolver implements Resolve<any> {

constructor(private store: Store<fromRoot.State>) {}

resolve(route: ActivatedRouteSnapshot, state: RouteStateSnapshot) {
  let id = route.params['id'];
  this.store.dispatch(new SelectAction(id));
  this.store.dispatch(new GetAction(id));
  return null;
}

И модифицированные маршруты:

[{
  path: ':id',
  component: ContainerComponent,
  resolve: {
    store: MyResolver
  }
}]

И поэтому я не уверен, что это правильно, потому что в магазине всегда будет null.


person bucicimaci    schedule 15.05.2017    source источник
comment
Вместо того, чтобы просто описывать код, включите его в вопрос.   -  person cartant    schedule 15.05.2017
comment
Я добавил код прихода.   -  person bucicimaci    schedule 15.05.2017
comment
да, отправка действия в резолвер - лучший подход. Компонент не будет ждать данных, он просто выполнит рендеринг. Также поделитесь своим кодом эффектов и редуктора.   -  person pTK    schedule 15.05.2017


Ответы (1)


Нет ничего плохого в том, как вы отправляете действия в ngOnInit на основе this.route.params.

Важно то, что резолверы являются поставщиками данных для маршрутов. А если вы не предоставляете данные, значит, вы их неправильно используете.

В вашем случае это больше похоже на canActivate охранника, который отвечает за выполнение действий и разрешение маршрута.


Тем не менее, вы можете расширить распознаватель для выбора нужных данных.

@Injectable({
    providedIn: 'root',
})
export class DataResolver implements Resolve<number> {
    constructor(private store: Store) {
    }

    public resolve(
        route: ActivatedRouteSnapshot,
        state: RouterStateSnapshot
    ): Observable<any> {
        this.store.dispatch(LoadDataForMyRoute());

        return this.store.pipe(
            select(dataForMyRoute),
            filter(data => !!data), // <- waiting until data is present
            take(1), // <- important to add
        );
    }
}

и в вашем компоненте вы можете получить к нему доступ, а не this.store.select.

constructor(
    protected readonly store: Store,
    protected readonly activatedRoute: ActivatedRoute,
) {}

public ngOnInit(): void {
    this.activatedRoute.data.subscribe(data => {
        // everything is here.
    });
}
person satanTime    schedule 16.05.2020