目前我正在尝试将令人敬畏的ngrx lib集成到我的项目中。一切都按照预期的@ ngrx / effects lib工作。我想要做的是从服务中获取我的一些数据,这将在稍后发出http请求。我知道我错过了一些东西,但我找不到我的误会。也许有些人可以提供帮助。
所以我在我的应用程序中有一个延迟加载的模块,我想使用ngrx lib。
到目前为止我的代码:
app.module.ts
import [...]
import { StoreModule } from '@ngrx/store';
import { StoreDevtoolsModule } from '@ngrx/store-devtools';
import { EffectsModule } from '@ngrx/effects';
@NgModule({
imports: [
HttpModule,
BrowserModule,
BrowserAnimationsModule,
ToastModule.forRoot(),
FormsModule,
SharedModule,
ReactiveFormsModule,
appRouting,
StoreModule.forRoot({}),
StoreDevtoolsModule.instrument({
maxAge: 25
}),
EffectsModule.forRoot([])
],
declarations: [
AppComponent,
NavigationComponent,
HomeComponent,
LoginComponent,
SidebarComponent,
PageNotFoundComponent
],
providers: [
AuthenticationService,
AlertService,
AuthGuard,
mockBackendProvider,
MockBackend,
BaseRequestOptions,
AppConfig,
{
provide: APP_INITIALIZER,
useFactory: (config: AppConfig) => () => config.load(),
deps: [AppConfig],
multi: true
},
{
provide: ToastOptions, useClass: NotificationOptions
}
],
bootstrap: [AppComponent]
})
export class AppModule {
}
project.module
import [...]
import { StoreModule } from '@ngrx/store';
import { EffectsModule } from '@ngrx/effects';
import { projectReducer } from './store/project.reducer';
import { ProjectService } from './services/project.service';
import { ProjectEffects } from './store/project.effects';
@NgModule({
imports: [
CommonModule,
FormsModule,
ReactiveFormsModule,
ProjectRoutingModule,
SharedModule,
EffectsModule.forFeature([ProjectEffects]),
StoreModule.forFeature('projectModule', {
projectReducer: projectReducer,
}),
],
exports: [],
declarations: [
HomeComponent,
DashboardComponent
],
providers: [
ProjectService,
mockBackendProvider,
MockBackend,
BaseRequestOptions
],
})
export class ProjectModule {
}
我创建了4个文件:
project.actions.ts
import { Action } from '@ngrx/store';
import { Project } from '../../../models/Project/Project';
export const SELECT_ALL_PROJECTS = '[projects] Select all';
export const ADD_PROJECT = '[projects] Add project';
export const DELETE_PROJECT = '[projects] Delete project';
export class GetAllProjectsAction implements Action {
readonly type = SELECT_ALL_PROJECTS;
constructor(public projects: Project[]) {
}
}
export class AddProjectAction implements Action {
readonly type = ADD_PROJECT;
constructor(public project: Project) {
}
}
export class DeleteProjectAction implements Action {
readonly type = DELETE_PROJECT;
constructor(public project: Project) {
}
}
export type Actions = GetAllProjectsAction | AddProjectAction | DeleteProjectAction;
projects.effects.ts
import { Injectable } from '@angular/core';
import {
Actions,
Effect
} from '@ngrx/effects';
import { Observable } from 'rxjs/Observable';
import { Action } from '@ngrx/store';
import * as projectAction from './project.actions';
import { ProjectService } from '../services/project.service';
import { of } from 'rxjs/observable/of';
@Injectable()
export class ProjectEffects {
@Effect() getAll$: Observable<Action> = this.actions$.ofType(projectAction.SELECT_ALL_PROJECTS)
.mergeMap(() =>
this._projectService.getAll()
.map((data: any[]) => ({type: projectAction.SELECT_ALL_PROJECTS, projects: data}))
.catch((error: any) => {
return of({type: 'getALL_Failed'})
})
);
constructor(private _projectService: ProjectService, private actions$: Actions) {
}
}
projects.reducer.ts
import * as projectAction from './project.actions';
import { ProjectState } from './project.state';
export const initialState: ProjectState = {
projects: [
{id: 1, title: 'Project Alpha'}, {id: 2, title: 'Project Beta'}]
};
export function projectReducer(state = initialState, action: projectAction.Actions): ProjectState {
switch (action.type) {
case projectAction.ADD_PROJECT:
return Object.assign({}, state, {
projects: state.projects.concat(Object.assign([], state, action.project))
});
case projectAction.SELECT_ALL_PROJECTS:
return Object.assign({}, state, action.projects);
case projectAction.DELETE_PROJECT:
return Object.assign({}, state, {
projects: state.projects.filter(p => p.id !== action.project.id)
});
default:
return state;
}
}
projects.state.ts
import { Project } from '../../../models/Project/Project';
export interface ProjectState {
projects: Project[];
}
最后我的服务:
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import {Project} from "../../../models/Project/Project";
@Injectable()
export class ProjectService {
projects: Project[] = [{
id: 1,
title: 'Project Alpha'
}];
constructor() {
}
getAll(): Observable<Project[]> {
return Observable.of(this.projects);
}
}
所以我在屏幕上看到的是2个初始项目,而不是项目服务给出的项目。看起来我在服务中或在reducer中做错了,或者我完全错过了其他的东西。
//更新: 我设法让效果起作用。好吧,至少效果被调用,但现在我被困在一个无限循环。该应用程序不会响应并显示白屏
也许有人可以帮助我 我在调用组件中的代码是:
import {DELETE_PROJECT, SELECT_ALL_PROJECTS} from '../../store/project.actions';
@Component({
selector: 'project-dashboard',
templateUrl: 'dashboard.component.html',
styleUrls: ['dashboard.component.scss']
})
export class DashboardComponent implements OnInit {
public async: any;
projectState$: Observable<ProjectState>;
constructor(private store: Store<any>) {
// this.store.dispatch({type: SELECT_ALL_PROJECTS});
this.projectState$ = this.store.select<ProjectState>(state => state.projectModule.projectReducer);
}
ngOnInit() {
this.store.dispatch({type: SELECT_ALL_PROJECTS, projects: []});
}
delete(project: Project) {
this.store.dispatch({type: DELETE_PROJECT, project: project})
}
}
感谢每一位帮助
此致
答案 0 :(得分:0)
你的无限循环是由于效果调度了它所观察到的相同动作。您需要调度SELECT_ALL_PROJECTS_COMPLETE
或类似物,然后在您的reducer中处理。
我意识到这是一个老问题,但也许它可以帮助别人,如果你设法自己解决这个问题:)