@ ngrx / store未正确订阅以进行选择

时间:2017-06-21 18:57:57

标签: angular ngrx ngrx-effects ngrx-store

我用@ ngrx / store创建了以下Angular 2应用程序,@ ngrx / efffects

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule,
    SharedModule,
    StoreModule.provideStore({mainStoreReducer}),
    EffectsModule.run(MainEffects)


  ],
  providers: [
    StompService
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

export interface State {
  counter: number;
  persons: any[];
  personsLoaded : boolean;
}

export const initialState: State = {
  counter: 10,
  persons: [],
  personsLoaded: false,
};


@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {

  title = 'app works!';
  data$;
  persons$;
  personForm: Person = <Person>{};

  persons = [];
  // state: State;

  constructor(private store: Store<State>,
              private http: Http,
              private stomp: StompService)  {
    // console.log(`We have a store! ${store}`);
    this.store.dispatch(CounterService.requestUsers);

    this.persons$ = store.select((state: State) => state.persons);
    this.data$ = store.select((state: State) => `Data is: ${state.counter}`);

  }
}

export interface Person {
  name: string,
  surname: string
}

<ul>
    <li *ngFor="let person of persons$ | async; let i = index">{{i}}. {{person.name}} {{person.surname}}</li>
</ul>

@Injectable()
export class MainEffects {

  constructor(private action$: Actions,
              private http: Http) {
  }

  @Effect() users$ = this.action$.ofType(CounterService.REQUEST_USERS)
    .switchMap(() => this.http.get("api/persons"))
    .map(res => res.json())
    .map(json => json._embedded.persons)
    .do(json => console.log(json))
    .switchMap(result => Observable.of(CounterService.receivedUsers(result)));
}


export const mainStoreReducer: ActionReducer<State> =
  (state = initialState, action: Action) : State => {

    console.log(`Action came in ! ${action.type}`);

    switch (action.type) {

      case CounterService.RECEIVED_USERS: {
        return {
          counter: state.counter,
          persons: action.payload,
          personsLoaded: true
        };
      }
      case CounterService.REQUEST_USERS: {
        console.log("requested users");
        return state;
      }
      default: {
        return state;
      }
    }
  };

好的,这些行似乎有问题:

`StoreModule.provideStore({mainStoreReducer})` and  

this.persons$ = store.select((state: State) => state.persons);

当我在mainStoreReducer中使用{}时,选择似乎无法正常工作。但是,如果我做StoreModule.provideStore(mainStoreReducer)那么它奇迹般地工作!显然我不能只这样做因为那只是一个减速器,所以在正常的项目中我会有多个减速器。

任何人都知道出了什么问题。如果您喜欢https://github.com/cgeo7/ngrx_tests_websockets_spring-boot,请直接查看github项目 它正常建立。

编辑:我已经做了那些修改,但我发现问题是状态在层次结构的第一级有reducer对象并且它包含实际状态。另外,如果我添加第二个reducer,它永远不会像mainStoreReducer那样初始化。这里有点可疑的东西

enter image description here

2 个答案:

答案 0 :(得分:2)

首先,您需要将Reducer导出为单个“reducer”,之后您应该执行:StoreModule.provideStore(reducer)。

检查此回购: https://github.com/onehungrymind/angular-applied-dashing/blob/master/src/app/common/reducers/index.ts

答案 1 :(得分:1)

您需要(键,值)对提供商店,以便您可以执行以下操作

StoreModule.provideStore( { mainStore: mainStoreReducer, anotherStore: anotherStoreReducer })

但是@coskun说你应该创建一个单独的文件并将reducers组合成一个reducer,然后将其导入到你的app组件中。希望这会有所帮助。