如何创建NGRX效果,如果可用,每5秒从状态获取一个记录



我想使用NGRX创建一个消息队列,添加到队列中的每条消息都应该显示5秒,然后从状态中删除

队列中的最后一条消息超时后,应将null值分配给currentMessageId
  • 如果currentMessageId == 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
    )
    )
    )
    );
    

    相关内容

    • 没有找到相关文章

    最新更新