SelectAll из ngrx / entity ничего не выбирает

вступление

У меня проблемы с работой селектора. Мой компонент не обновляется книгами из FakeApiService, хотя я вижу, что звонок сделан. Итак, действия и эффекты работают.

Я считаю, что проблема связана с тем, что я использую @ngrx/Entity. Конкретно это

export const getBooksState = createFeatureSelector<DemoState>('demo');

а также

export const { selectAll } = fromBook.adapter.getSelectors();

Я видел учебные пособия, в которых getSelectors() предоставляется функция выбора, но в этом нет необходимости.

Я надеюсь, что кто-то поймет, в чем я ошибаюсь, и если у кого-то есть предложения по структуре / настройке, я все слышу :)

Вот моя установка.

Версии

  • Угловой: 6.0.0
  • rxjs 6.1.0
  • машинописный текст 2.7.2
  • webpack 4.6.0
  • @ ngrx / эффекты 5.2.0
  • @ ngrx / сущность 5.2.0
  • @ ngrx / роутер-магазин 5.2.0
  • @ ngrx / схемы 5.2.0
  • @ ngrx / магазин 5.2.0
  • @ ngrx / магазин-devtools 5.2.0

ngRx

особенность / магазин / действия / book.actions.ts

import { Action } from '@ngrx/store';
import { Book } from '../../models/book';

export enum BookActionTypes {
  Load = '[Book] Load',
  LoadSuccess = '[Book] Load Success',
  LoadFail = '[Book] Load Fail'
}

export class LoadBooksAction {
  readonly type = BookActionTypes.Load;
}

export class LoadBooksSuccessAction implements Action {
  readonly type = BookActionTypes.LoadSuccess;
  constructor(public payload: Book[]) {}
}

export class LoadBooksFailAction {
  readonly type = BookActionTypes.LoadFail;
}

export type BookActions
  = LoadBooksAction
  | LoadBooksSuccessAction
  | LoadBooksFailAction;

особенность / магазин / эффекты / book.effects.ts

import { Injectable } from '@angular/core';
import { Actions, Effect } from '@ngrx/effects';
import { of } from 'rxjs';
import { catchError, map, switchMap } from 'rxjs/operators';
import { FakeApiService } from '../../services/fake-api.service';
import { LoadBooksFailAction, LoadBooksSuccessAction, BookActionTypes } from '../actions/book.actions';

@Injectable()
export class BookEffects {
    constructor(
        private fakeService: FakeApiService,
        private actions$: Actions,
    ) {}

    @Effect()
    loadBooks$ = this.actions$
      .ofType(BookActionTypes.Load)
      .pipe(
        switchMap(() => this.fakeService.getBooks()),
        map(books => (new LoadBooksSuccessAction(books))),
        catchError(error => of(new LoadBooksFailAction()))
      );
}

функция / магазин / редукторы / book.reducer.ts

import { EntityState, createEntityAdapter } from '@ngrx/entity';
import { Book } from '../../models/book';
import { BookActionTypes, BookActions } from './../actions/book.actions';

export interface BooksState extends EntityState<Book> {}

export const adapter = createEntityAdapter<Book>();

const initialState: BooksState = adapter.getInitialState();

export function reducer(state = initialState, action: BookActions ): BooksState {
  switch (action.type) {
    case BookActionTypes.LoadSuccess: {
      return adapter.addAll(action.payload, state);
    }

    default: {
      return state;
    }
  }
}

функция / магазин / редукторы / index.ts

import { ActionReducerMap, createFeatureSelector } from '@ngrx/store';
import * as fromOrder from './book.reducer';

export interface DemoState {
  demo: fromBook.BooksState;
}

export const reducers: ActionReducerMap<DemoState> = {
  demo: fromBook.reducer
};

export const getBooksState = createFeatureSelector<DemoState>('demo');

функция / магазин / селекторы / book.selectors.ts

import * as fromBook from '../reducers/book.reducer';

export const {selectAll} = fromBook.adapter.getSelectors();

Угловой

функция / feature.module.ts

@NgModule({
  imports: [
    CommonModule,
    StoreModule.forFeature('demo', reducer),
    EffectsModule.forFeature([BookEffects])
  ],
  providers: [FakeApiService],
  declarations: []
})
export class DemoModule { }

особенность / компоненты / book-view.component.ts

@Component({
  selector: 'app-book-view',
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `<book-list [books]="books$ | async"></book-list>`
})
export class BookViewComponent implements OnInit {
  books$: Observable<Book[]>;

  constructor(private store: Store<fromStore.BooksState>) {
    this.books$ = this.store.pipe(select(fromStore.selectAll));
  }

  ngOnInit() {
    this.store.dispatch(new bookActions.LoadBooksAction());
  }
}

person Snæbjørn    schedule 14.05.2018    source источник
comment
поместите это в stackblitz   -  person rijin    schedule 14.05.2018


Ответы (1)


Проблема с вашим селектором; Вы должны передать состояние книги / демонстрации в функции getSelectors

import * as fromBook from '../reducers/book.reducer';

import { getBooksState } from '../reducers';

export const selectBookState = createSelector(
  getBooksState,
  state => state.demo
);

export const {
  selectAll
} = fromBook.adapter.getSelectors(selectBookState);

посмотри на мое репо и URL

https://github.com/rijine/itunes-album-angular/blob/master/src/app/album/store/selectors/albums.selector.ts

person rijin    schedule 14.05.2018
comment
Похоже на демонстрации / руководства, которые я видел в сети. Я не понимаю необходимости селектора состояний. Я думаю, это было бы возможно и без этого. - person Snæbjørn; 14.05.2018
comment
Я думал так же, как вы думаете сейчас. У меня было такое же замешательство, затем я задал такой же вопрос и в ngrx gitter. Надеюсь, что это поможет вам. - person rijin; 15.05.2018
comment
Это очень легко понять, вы можете поставить точку останова в селекторе stateBookState и проверить значение state.demo! - person rijin; 15.05.2018