Как работать с фильтрами для моего магазина ngrx? - PullRequest
0 голосов
/ 16 апреля 2020

Как обработать функцию фильтра для моего магазина?

В настоящее время он извлекает данные из внешнего источника с помощью службы с помощью эффектов.

Как только мы получим данные, они будут доступны внутри. мой магазин.

Итак, я хочу отфильтровать сущности в моем магазине (локальное хранилище ngrx, а не резервную базу данных) на основе некоторых критериев фильтрации.

это интерфейс элемента.

export interface item {
    id: string;
    name: string;
    price: number;
    location: string;
    category: string;
    ...
}
// component.ts

this.store.dispatch(loadItems())

this.Items$ = this.store.pipe(select(selectItems))

//actions.ts

export const loadItems = createAction(
    '[Item Items Component] Load Items',
  );
  export const loadItemsSuccess = createAction(
    '[Item Items/API] Load Items Success',
    props<{ Items: Item[] }>()
  );
  export const loadItemsFailure = createAction(
    '[Item Items/API] Load Items Failure',
    props<{ error: any }>()
  );


// effects.ts

loadItems$ = createEffect(() =>
this.actions$.pipe(
  ofType(ItemActions.loadItems),
  mergeMap(action =>
    this.defaultService.getContentModeration().pipe(
      map(Items => ItemActions.loadItemsSuccess({ Items })),
      catchError(error =>
        of(ItemActions.loadItemsFailure({ error }))
      )
    )
  )
)
)



// selector.ts

export const selectItemState = createFeatureSelector<ItemState>(
  ItemsFeatureKey
);

export const selectItems = createSelector(selectItemState, selectAll);

// reducer.ts

export const ItemsFeatureKey = 'Items';

export interface ItemState extends EntityState<Item> {
  // additional entities state properties
  error: any;
}

export const adapter: EntityAdapter<Item> = createEntityAdapter<Item>({
  sortComparer: (c1: Item, c2: Item) => {
    const compare = c1.timestamp - c2.timestamp;
    return compare > 0 ? 11 : compare < 0 ? 1 : 0
  },
  selectId: Item => Item.contentId,
});

export const initialState: ItemState = adapter.getInitialState({
  // additional entity state properties
  error: undefined
});

export const reducer = createReducer(
  initialState,
  on(ItemActions.loadItemsSuccess,
    (state, action) => adapter.setAll(action.Items, state)
  ),
  on(ItemActions.loadItemsFailure,
    (state, action) => {
      return {
        ...state,
        error: action.error
      }
    }
  ),

  export const {
    selectIds,
    selectEntities,
    selectAll,
    selectTotal,
  } = adapter.getSelectors();

В настоящее время я использую трубу фильтра. но это нереально. Это замедляет мое приложение. Я хочу использовать потенциал магазина, который обрабатывает состояние

Поэтому я хочу отфильтровать товары (сущности) в магазине по названию, цене, категории или по объединенному имени, цене, категории. Как и обычные фильтры, которые мы видим на таких сайтах, как amazon, flipkart и др. c ...

Я думаю, что все решения устарели (некоторые из них используют операторы switch, но недавно включены селекторы ngrx ( ) метод и действия также отличаются от предыдущих версий) .

Может кто-нибудь помочь, пожалуйста?

Если у вас нет времени, чтобы ответить, скажите, пожалуйста, это тупик или нет. Так что я могу продолжать использовать каналы и прекратить поиск дальше.

1 Ответ

0 голосов
/ 16 апреля 2020

Если вам нужно несколько потоков отфильтрованных данных из одного хранилища (или производного состояния), используйте селекторы с реквизитом:


// selectors
export const selectFilteredItems = createSelector(
  selectItemState, 
  selectAll, 
  (items, props) => items.filter(entity => entity.name === props.name)
);
export const selectFilteredByTypeItems = () => {}


//component
this.filteredByNameItems$ = this.store.select(selectFilteredItems, {name: 'name1'});
this.filteredByTypeItems$ = this.store.select(selectFilteredByTypeItems, {type: 'type1'});

, если вы хотите установить фильтр из пользовательского интерфейса, вы должны сохранить этот фильтр в состоянии и используйте этот фильтр в селекторах:

// reducers
const initialState = {
  filter: {name: '', type: ''}
}

// selectors
export const selectFilter = createSelector(
  selectItemState,
  state => state.filter
);

export const selectFilteredItems = createSelector(
  selectItems,
  selectFilter,
  ([allItems, uiFilter]) => allItems.filter(item => item.name === uiFilter.name)
); // note the combination of two selectors: for all items and for the filter

не забудьте добавить действия и редукторы для управления фильтром пользовательского интерфейса

...