使用NgRx /效果自动完成材料

时间:2019-09-06 15:07:29

标签: angular-material ngrx ngrx-effects

我正在尝试使用NgRx / effects在角度8中自动完成的材质。

我已经创建了商店,动作,效果和缩减器,但是在成功调用api之后我没有得到状态。 api返回正确的值。

动作文件

import { Action } from '@ngrx/store';
import {IProviderSearchObject} from '../../models/provider.type';

export enum ProviderSearchActionTypes {
  SearchProvidersRequest = '[SEARCH_PROVIDER] REQUEST',
  SearchProvidersSuccess = '[SEARCH_PROVIDER] SUCCESS',
  SearchProvidersFail = '[SEARCH_PROVIDER] FAILED'
}

export class ProviderSearchAction implements Action {
  type: string;
  payload: {
    isRequesting: boolean,
    providers: Array<IProviderSearchObject>,
    error: boolean,
    searchPhrase: string
  };
}

export class SearchProvidersRequest implements Action {
  readonly type = ProviderSearchActionTypes.SearchProvidersRequest;
  constructor(readonly payload: {isRequesting: boolean, searchPhrase: string}) {}
}

export class SearchProvidersSuccess implements Action {
  readonly type = ProviderSearchActionTypes.SearchProvidersSuccess;
  constructor(readonly payload: {isRequesting: boolean, providers: Array<IProviderSearchObject>}) {}
}

export class SearchProvidersFail implements Action {
  readonly type = ProviderSearchActionTypes.SearchProvidersFail;
  constructor(readonly payload: {error: boolean}) {}
}

export type ProviderSearchActions = SearchProvidersRequest | SearchProvidersSuccess | SearchProvidersFail;

归约文件

import {IProviderSearchObject} from '../../models/provider.type';
import {ProviderSearchAction, ProviderSearchActionTypes} from '../actions/provider-search.action';

export interface IProviderSearchState {
  isRequesting: boolean;
  providers: Array<IProviderSearchObject> | null;
  error: boolean;
}

const initialProviderSearchState: IProviderSearchState = {
  isRequesting: false,
  providers: null,
  error: false
};

export function providerSearchReducer(state: IProviderSearchState = initialProviderSearchState, action: ProviderSearchAction): IProviderSearchState {
  console.log(action, state);
  switch (action.type) {
    case ProviderSearchActionTypes.SearchProvidersRequest:
      return {
        isRequesting: true,
        providers: null,
        error: false
      };
    case ProviderSearchActionTypes.SearchProvidersSuccess:
      return {
        isRequesting: false,
        providers: action.payload.providers,
        error: false
      };
    case ProviderSearchActionTypes.SearchProvidersFail:
      return {
        isRequesting: false,
        providers: null,
        error: true
      }
    default:
      return state;
  }
}

import {ActionReducerMap, MetaReducer} from '@ngrx/store';
import {IProviderSearchState, providerSearchReducer} from './provider-search.reducer';

export interface IAppState {
  providerSearch: IProviderSearchState;
}

export const reducers: ActionReducerMap<IAppState> = {
  providerSearch: providerSearchReducer
};

export const selectProviderSearch = (state: IAppState) => state.providerSearch.providers;

export const metaReducers: MetaReducer<any>[] = [];

效果文件

import {Actions, Effect, ofType} from '@ngrx/effects';
import {IAppState} from '../reducers';
import {ProviderSearchService} from '../../modules/provider-search/services/provider-search.service';
import {Store} from '@ngrx/store';
import {ProviderSearchActionTypes, SearchProvidersSuccess, SearchProvidersFail} from '../actions/provider-search.action';
import {catchError, map, switchMap} from 'rxjs/operators';
import { of } from 'rxjs';
import {IProviderSearchObject} from '../../models/provider.type';
import {Injectable} from '@angular/core';

@Injectable()
export class ProviderSearchEffects {

  constructor(private actions$: Actions,
              private store: Store<IAppState>,
              private providerSearchService: ProviderSearchService) {}

  @Effect()
  searchProvider$ = this.actions$
    .pipe(
      ofType<any>(ProviderSearchActionTypes.SearchProvidersRequest),
      map(action => action.payload),
      switchMap((action) => {
        return this.providerSearchService.getProviderByPhrase(action.searchPhrase).pipe(
          map((data: Array<IProviderSearchObject>) => new SearchProvidersSuccess({isRequesting: false, providers: data})),
          catchError(error => of(new SearchProvidersFail({error: true})))
        );
      })
    );
}

import { ProviderSearchEffects } from './provider-search.effects';
export const effects: Array<any> = [ProviderSearchEffects];

服务文件

import { Injectable } from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {environment} from './../../../../environments/environment';
import { Store } from '@ngrx/store';
import * as ProviderSearchAction from '../../../store/actions/provider-search.action';
import {IAppState} from '../../../store/reducers';
import {Observable} from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class ProviderSearchService {

  constructor(
    private http: HttpClient,
    private store: Store<IAppState>
  ) { }

  public getProviderByPhrase = (searchPhrase: string): Observable<any> => {
    return this.http.get('https://mydummyapi.com?q=' + searchPhrase);
  }
  public searchProviderByTermSearch = (searchPhrase: string): any => {
    return this.store.dispatch(new ProviderSearchAction.SearchProvidersRequest({isRequesting: true, searchPhrase}));
  }
}

组件文件

ngOnInit() {
    this.providerSearchControl.valueChanges
    .pipe(
      debounceTime(500),
      tap(() => {
        this.isLoading = true;
      }),
      switchMap((value: string) => this.providerSearchService.searchProviderByTermSearch(value))
      .pipe(
        finalize(() => {
          this.isLoading = false;
        })
      )
      )
    )
    .subscribe((data: Array<IProviderSearchObject>) => {
      console.log(data);
      if (data && data.length > 0) {
        this.providerSearchResult = data;
      }
    });
  }

当用户开始输入自动完成字段时,会在服务文件中调用 searchProviderByTermSearch 方法,并分派操作。

但是在 [SEARCH_PROVIDER]成功调用后,什么都没有发生。

1 个答案:

答案 0 :(得分:0)

store.dispatchvoid,它返回值。 data代码中的subscribe不是 Array<IProviderSearchObject>

您的流量应为:

  • 调度获取
  • 通话服务效果
  • 调度获取成功/失败
  • 通过reducer更新状态
  • 使用选择器读取数据
  • 更新组件

https://ngrx.io/guide/store#diagram

相关问题