ngrx/Store和reducer都是新手.基本上,我有这个减速器:
import {StoreData, INITIAL_STORE_DATA} from "../store-data";
import {Action} from "@ngrx/store";
import {
USER_THREADS_LOADED_ACTION, UserThreadsLoadedAction, SEND_NEW_MESSAGE_ACTION,
SendNewMessageAction
} from "../actions";
import * as _ from "lodash";
import {Message} from "../../shared-vh/model/message";
import {ThreadsService} from "../../shared-vh/services/threads.service";
export function storeData(state: StoreData = INITIAL_STORE_DATA, action: Action): StoreData {
switch (action.type) {
case SEND_NEW_MESSAGE_ACTION:
return handleSendNewMessageAction(state, action);
default:
return state
}
}
function handleSendNewMessageAction(state:StoreData, action:SendNewMessageAction): StoreData {
const newStoreData = _.cloneDeep(state);
const currentThread = newStoreData.threads[action.payload.threadId];
const newMessage: Message = {
text: action.payload.text,
threadId: action.payload.threadId,
timestamp: new Date().getTime(),
participantId: action.payload.participantId,
id: [need a function from this service: ThreadsService]
}
currentThread.messageIds.push(newMessage.id);
newStoreData.messages[newMessage.id] = newMessage;
return newStoreData;
}
问题出在reducer函数中,我不知道如何注入我在不同文件中创建的可注入服务并使用其中的函数.id部分 - 我需要使用像this.threadService.generateID()这样的函数生成firebase推送ID ...
但由于这是一个函数,我没有使用DI的构造函数,我不知道如何在threadService中获取函数!
没有为减压器注入服务的机制.减速器应该是纯粹的功能.
相反,您应该使用ngrx/effects
- 这是实现动作副作用的机制.效果侦听特定操作,执行一些副作用,然后(可选)发出进一步的操作.
通常,您会将操作拆分为三个:请求; 成功的反应; 和错误响应.例如,您可以使用:
SEND_NEW_MESSAGE_REQ_ACTION
SEND_NEW_MESSAGE_RES_ACTION
SEND_NEW_MESSAGE_ERR_ACTION
你的效果看起来像这样:
import { Injectable } from "@angular/core";
import { Actions, Effect, toPayload } from "@ngrx/effects";
import { Action } from "@ngrx/store";
import { Observable } from "rxjs/Observable";
import "rxjs/add/operator/map";
@Injectable()
export class ThreadEffects {
constructor(
private actions: Actions,
private service: ThreadsService
) {}
@Effect()
sendNewMessage(): Observable {
return this.actions
.ofType(SEND_NEW_MESSAGE_REQ_ACTION)
.map(toPayload)
.map(payload => {
try {
return {
type: SEND_NEW_MESSAGE_RES_ACTION,
payload: {
id: service.someFunction(),
// ...
}
};
} catch (error) {
return {
type: SEND_NEW_MESSAGE_ERR_ACTION
payload: {
error: error.toString(),
// ...
}
};
}
});
}
}
而不是与服务交互,您的reducer将是一个纯函数,只需要处理SEND_NEW_MESSAGE_RES_ACTION
和SEND_NEW_MESSAGE_ERR_ACTION
执行适当的成功或错误有效负载.
效果是基于可观察的,因此合并同步,基于承诺或基于可观察的服务是直截了当的.
有一些影响的ngrx/example-app
.
关于您在评论中的查询:
这.map(toPayload)
只是为了方便.toPayload
是一个ngrx
存在的函数,因此它可以传递.map
给提取动作payload
,这就是全部.
调用基于可观察的服务是直截了当的.通常,你会做这样的事情:
import { Observable } from "rxjs/Observable";
import "rxjs/add/observable/of";
import "rxjs/add/operator/catch";
import "rxjs/add/operator/map";
import "rxjs/add/operator/switchMap";
@Effect()
sendNewMessage(): Observable {
return this.actions
.ofType(SEND_NEW_MESSAGE_REQ_ACTION)
.map(toPayload)
.switchMap(payload => service.someFunctionReturningObservable(payload)
.map(result => {
type: SEND_NEW_MESSAGE_RES_ACTION,
payload: {
id: result.id,
// ...
}
})
.catch(error => Observable.of({
type: SEND_NEW_MESSAGE_ERR_ACTION
payload: {
error: error.toString(),
// ...
}
}))
);
}
此外,效果可以声明为返回的函数Observable
或类型的属性Observable
.如果您正在查看其他示例,则可能会遇到两种形式.