代码之家  ›  专栏  ›  技术社区  ›  Or Yaacov

Angular ngrx 8选择器不返回任何值

  •  0
  • Or Yaacov  · 技术社区  · 5 年前

    我对Angular并不陌生,但我对ngrx很陌生。 我试图从我的服务器获取一些值,然后简单地将它们打印到屏幕上,我可以看到这些值是从服务器返回的,之后效果捕捉到操作并执行它的工作:

    enter image description here

    export class ProfileComponent implements OnInit {
      network$= this.store.select(a=>a.NetworkInfo)
      profiles$: Observable<Profile[]> = this.store.select(state => state.Profiles);
      constructor(private store:Store<NetAlertState>) { }
    
      ngOnInit() {
        this.store.dispatch({ type: '[Profile Component] getAllProfiles' });
        this.store.dispatch({ type: '[Profile Component] getNetworkInfo' });    
      }
    
    }
    

    profile.component.html:

        <div *ngFor="let profile of profiles$ | async">
        {{ profile.name }}
        </div>
    

    net-alert.actions.ts:

    export const getAllProfiles = createAction('[Profile Component] getAllProfiles');
    export const getNetworkInfo = createAction('[Profile Component] getNetworkInfo');
    export const loadProfilesSuccess = createAction('[Profile Component] loadProfilesSuccess',props<{items:Profile[]}>());
    export const loadNetworkInfoSuccess = createAction('[Profile Component] loadNetworkInfoSuccess', props<NetworkInfo>());
    export const loadProfilesFailure = createAction('[Profile Component] loadProfilesFailure',props<String>());
    export const loadNetworkInfoFailure = createAction('[Profile Component] loadNetworkInfoFailure',props<String>());
    

    net-alert.reducer.ts

        export const initialState: NetAlertState = {
        Profiles:null,
        NetworkInfo:null,
        isLoading: false,
        error: null
    }
    
    export const NetAlertReducer = createReducer(
        initialState,
        on(NetAlertActions.getAllProfiles, state => ({ ...state,isLoading:true ,error:null})),
        on(NetAlertActions.loadProfilesSuccess, (state,profiles) => ({ Profiles:profiles,...state ,isLoading:false ,error:null})),
        on(NetAlertActions.loadProfilesFailure, (state,err) => ({ ...state,isLoading:false ,error:err})),
        on(NetAlertActions.getNetworkInfo, state => ({ ...state ,isLoading:true ,error:null})),
        on(NetAlertActions.loadNetworkInfoSuccess, (state,res) => ({ ...state,NetworkInfo:res,isLoading:false ,error:null})),
        on(NetAlertActions.loadNetworkInfoFailure, (state,err) => ({ ...state,isLoading:false ,error:err})),
      );
    
    
    
    export function reducer(state: NetAlertState | undefined, action: Action) {
        return NetAlertReducer(state, action);
      }
    

    @Injectable()
    export class NetAlertEffects {
    
        loadProfiles$ = createEffect(() =>
         this.actions$.pipe(
            ofType('[Profile Component] getAllProfiles'),
            mergeMap(() => this.dataService.getAllProfiles()
              .pipe(
                map(res => ({ type: '[Profile Component] loadProfilesSuccess', payload: res })),
                catchError(() => of({ type: '[Profile Component] loadProfilesFailure' }))
              )
            )
          )
      );
    
      constructor(
        private actions$: Actions,
        private dataService: DataService
      ) {}
    }
    

    net-alert.state.ts:

      export interface NetAlertState {
         isLoading: boolean;
         error: any;
         NetworkInfo: NetworkInfo;
         Profiles: Profile[];
     }
    
     export interface Profile {
      Mac: string;
      NickName: string;
      CreateDate: Date;
      Sites?: any;
    }
    

    根状态.ts:

    export interface AppStates {
      netAlert: NetAlertState;
    }
    
    export const netAlertReducers: ActionReducerMap<AppStates> = {
        netAlert: netAlertRerucers.reducer
     }; 
    

    应用模块ts:

      @NgModule({
      declarations: [
        AppComponent,
        ProfileContainerComponent,
        ProfileComponent
      ],
      imports: [
        HttpClientModule,
        BrowserModule,
        AppRoutingModule,
        StoreModule.forRoot(netAlertReducers),
        EffectsModule.forRoot([NetAlertEffects]),
        StoreDevtoolsModule.instrument({
          maxAge: 25, // Retains last 25 states
          logOnly: environment.production, // Restrict extension to log-only mode
        }),
        RootStoreModule
      ],
      providers: [],
      bootstrap: [AppComponent]
    })
    export class AppModule { }
    

    有人能告诉我哪里错了吗?

    谢谢!

    0 回复  |  直到 5 年前
        1
  •  1
  •   HTN    5 年前

    如果你没有一个reducer来更新你的状态,它就不起作用了 loadProfilesSuccess

    const myReducer = createReducer(
      initialState, // type NetAlertState
      on(from.loadProfilesSuccess, (state, action) => {
         // return new state from action payload
      }),
    )
    
    export function reducer(state: NetAlertState, action: Action) {
        return myReducer(state, action);
    }
    

    ngOnInit() {
        this.store.dispatch(getAllProfiles());
        this.store.dispatch(getNetworkInfo());
    }
    
    loadProfiles$ = createEffect(() =>
         this.actions$.pipe(
            ofType(getAllProfiles),
            mergeMap(() => this.dataService.getAllProfiles()
              .pipe(
                map(res => loadProfilesSuccess(res)),
                catchError(() => of(loadProfilesFailure())
              )
            )
          )
        );
    
        2
  •  1
  •   Andrew Allen    5 年前

    我没有看到用于选择“netAlert”状态的选择器,您可以在其上构建其他选择器,如下所示:

    import * as fromNetAlertState from "./state";
    
    export const netAlertState = (state: State) => state.netAlert;
    
    export const selectProfiles = createSelector(
      netAlertState,
      (state: fromNetAlertState.State) => state.Profiles
    );
    

    组件.ts

    profiles$: Observable<Profile[]> 
    
    ngOnInit() {
        this.profiles$ = this.store.pipe(select(selectProfiles))
    }
    
        3
  •  1
  •   Tony Ngo    5 年前

    export class ProfileComponent implements OnInit {
      network$: any;
      profiles$: Observable<Profile[]>
      constructor(private store:Store<NetAlertState>) { }
    
      ngOnInit() {
        this.store.dispatch({ type: '[Profile Component] getAllProfiles' });
        this.store.dispatch({ type: '[Profile Component] getNetworkInfo' });
        this.network$ =  this.store.select(a=>a.NetworkInfo);
        this.profiles$ = this.store.pipe(select(state => state.Profiles));
      }
    }
    

    也可以尝试使用管道操作符

    推荐文章