0

@ngrx/store、@ngrx/efffects を使用して、次の Angular 2 アプリケーションを作成しました。

@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)、それは奇跡的に機能します! . 明らかに、それは1つのレデューサーにすぎないため、それだけを行うことはできません。通常のプロジェクトでは、複数のレデューサーがあります。

誰でも何がうまくいかないのか考えています。よかったらgithubプロジェクトを直接見てみてくださいhttps://github.com/cgeo7/ngrx_tests_websockets_spring-boot 正常にビルドされています。

編集:これらの変更を行いましたが、問題は、階層の最初のレベルに状態のレデューサー オブジェクトがあり、実際の状態が含まれていることです。さらに、2 番目のレデューサーを追加すると、これは のように初期化されることはありませんmainStoreReducer。ここに怪しいものがあります

ここに画像の説明を入力

4

2 に答える 2

2

まず、レデューサーを単一の「レデューサー」にエクスポートする必要があります。その後、StoreModule.provideStore(reducer) を実行する必要があります。

このリポジトリを確認してください: https://github.com/onehungrymind/angular-applied-dashing/blob/master/src/app/common/reducers/index.ts

于 2017-06-21T19:30:18.943 に答える
1

ストアを提供するには(キー、値)ペアが必要なので、代わりに次のことができます

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

しかし、@coskun が言ったように、別のファイルを作成し、レデューサーを 1 つのレデューサーに結合してから、それをアプリ コンポーネントにインポートする必要があります。これが役立つことを願っています。

于 2017-06-21T21:25:13.633 に答える