Jur*_*hen 1 typescript redux ngrx angular angular5
我正在开发一个相对简单的应用程序,我想了解更多有关ngrx,redux和angular 2的信息.
我将简要介绍一下我的app,appstate和reducer的设置.
在我的应用程序中,我想使用webgl框架在我的屏幕上绘制某些对象(网格).我想通过创建具有这些网格属性的简单对象,并通过ngrx存储添加网格,并将其保存在应用程序状态中.每当添加"网格"时,我想使用ngrx sideeffects在屏幕上使用可访问webgl框架的服务绘制网格.
我的(简化)appstate看起来像这样:
export interface AppState {
meshList: MeshListReducer.MeshListState
}
Run Code Online (Sandbox Code Playgroud)
要添加网格,我创建了以下reducer函数:
case MeshActions.ADD_MESH: {
return Object.assign({
entities: [meshAction.payload, ...state.entities]
});
}
case MeshActions.ADD_MESH_SUCCESS:
case MeshActions.UPDATE_MESH: {
// This reducer function is only being called once, see below for further explanation.
return Object.assign({}, state, {
entities: state.entities.map(meshItem => {
// If we can find a mesh with this id, use the sub reducer to update it.
if (meshItem.uuid === meshAction.payload.uuid)
return meshSubReducer(meshItem, meshAction);
return meshItem;
})
});
}
default: {
return state;
}
}
export function meshSubReducer(mesh: BaseMesh, meshAction: MeshAction): BaseMesh {
switch (meshAction.type) {
case MeshActions.ADD_MESH_SUCCESS:
case MeshActions.UPDATE_MESH:
return Object.assign({}, meshAction.payload);
default:
return mesh;
}
}
Run Code Online (Sandbox Code Playgroud)
最后我的effect类包含对webgl框架服务的调用,并调用succes动作:
@Effect()
addMesh$ = this.actions$
.ofType(MeshActions.ADD_MESH)
.map((action: MeshAction) => action.payload)
.switchMap((payload: BaseMesh) => this._worldService.addMeshToWorld(payload))
.map(payload => this._meshActions.addMeshSuccess(payload));
Run Code Online (Sandbox Code Playgroud)
和worldService.addMeshToWorld函数:
public addMeshToWorld(mesh: BaseMesh): Promise<BaseMesh> {
let p = new Promise<BaseMesh>((resolve, reject) => {
let renderer = this._meshRendererFactory.createMeshRenderer(mesh);
// Every call to the ngrx effects always enters this function, and the component is sucessfully added to the canvas.
renderer.addTo(this._world.app).then((component: WHS.Component) => {
resolve(Object.assign({}, mesh, {
rendererId: (<any>component).native.id
}));
});
});
return p;
}
Run Code Online (Sandbox Code Playgroud)
我正在使用这些调度方法调用所有这些函数:
let soccerBall = new SphereMesh({
geometry: {
heightSegments: 20,
widthSegments: 20,
radius: 5
},
gameMeshType: Enums.GameMeshType.Sphere,
uuid: this._meshHelper.generateUUID(),
meshMaterial: {
color: 0xF2F2F2
}
});
let soccerBall2 = new SphereMesh({
geometry: {
heightSegments: 20,
widthSegments: 20,
radius: 5
},
gameMeshType: Enums.GameMeshType.Sphere,
uuid: this._meshHelper.generateUUID(),
meshMaterial: {
color: 0xF2F2F2
}
});
// Dispatching these straight after each other will cause the succes action to only be dispatched once.
this._store.dispatch(this._meshActions.addMesh(soccerBall));
this._store.dispatch(this._meshActions.addMesh(soccerBall2));
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是,在调用"ADD_MESH"副作用并将网格添加到屏幕后,效果仅调用最终的"map"动作一次,因此ADD_MESH_SUCCES减速器函数仅针对一个网格调用,而不是其他,见截图:
奇怪的是,当我在超时中添加第二个调度时,现在突然为所有调度的项正确调用成功调用:
this._store.dispatch(this._meshActions.addMesh(soccerBall));
setTimeout(() => {
// Now succes action is suddenly being called twice like it should..
this._store.dispatch(this._meshActions.addMesh(soccerBall2));
}, 1500);
Run Code Online (Sandbox Code Playgroud)
什么可能导致这种奇怪的行为?我认为我的应用程序相当简单,但似乎我错过了一些东西.
我正在使用以下软件包版本(我选择了我认为最有用的软件包:
"@angular/core": "^5.0.0",
"rxjs": "^5.5.2",
"@ngrx/effects": "^5.2.0",
"@ngrx/store": "^5.0.0",
"typescript": "~2.4.2"
Run Code Online (Sandbox Code Playgroud)
必须switchMap仔细使用内部效果,我的建议是在你熟悉RxJS之前不要使用它.
为什么switchMap很危险?因为第二次在第一次操作完成之前调度相同的操作,它会禁用第一个启动的链并立即执行第二个操作链.
为何concatMap有效?它排队行动.第一个完成后,第二个开始.所以行动之间没有竞争.
| 归档时间: |
|
| 查看次数: |
3146 次 |
| 最近记录: |