如果
我想使用NGRX创建一个消息队列,添加到队列中的每条消息都应该显示5秒,然后从状态中删除
队列中的最后一条消息超时后,应将null值分配给currentMessageIdcurrentMessageId == null
,则应立即从队列中获取消息这是我的状态:
import { EntityState } from '@ngrx/entity';
export interface UiMessage {
id: string;
severity: 'info' | 'warn' | 'error' | 'success';
summary?: string;
detail: string;
}
export interface MessagesState extends EntityState<UiMessage>{
currentMessageId: string;
}
我已经尝试过这个代码,如果商店里总是有一条消息,它会很好地工作:
takeMessageInterval$ = createEffect(() => {
return timer(0, 5000).pipe(
map(() => {
return UiActions.takeNextMessage()
})
)
});
但考虑一下这种情况:
- 当存储中没有消息时,效果计时器在第0秒启动
- 一条消息在第1秒被添加到存储中,然后消息必须等待4秒才能勾选,然后显示在视图中
- 我希望它能尽快显示,并在5秒钟后删除
这里还有减速器功能:
export const messagesReducer = createReducer<MessagesState>(
initialState,
on(UiActions.addStateMessage, (current, action) => {
return messagesAdapter.addOne(action.message, current);
}),
on(UiActions.removeStateMessage, (current, action) => {
return messagesAdapter.removeOne(action.id, current);
}),
on(UiActions.takeNextMessage, (current, action) => {
// remove current message
if (current.currentMessageId) {
current = messagesAdapter.removeOne(current.currentMessageId, current);
}
// take next message id
const nextId = current.ids[0] as string;
current.currentMessageId = nextId;
return current;
}),
);
这里可能有一种方法,假设一次只能显示一条消息:
takeMessageInterval$ = createEffect(
() => this.actions$.pipe(
// Intercept when a message has been added
ofType(UiActions.addStateMessage),
concatMapTo( // Queue up the messages
timer(5000).pipe( // Display it for 5 seconds
endWith(UiActions.takeNextMessage()) // Display the next message and remove the current one
)
)
)
);