Открытие модального режима с использованием NGX и управления состоянием - PullRequest
0 голосов
/ 01 июля 2019

Я бы хотел использовать NGXS, чтобы открыть модальный режим, который установит видимость столбцов для данных.

Вот мой код:

файл state.ts:

@Action(OpenColumnModal)
openColumnModal(ctx: StateContext<FeedStateModel>) {
    const state = ctx.getState();
    const allCols = state.allColumns;
    return this.modalService.openColumnVisibilityModal(allCols).pipe(tap((result) => {
        ctx.setState({
            ...state,
            allColumns: result,
            userColumns: result.filter(col => col.visible)
        });
    })
}

modal.service.ts:

openColumnVisibilityModal(columns): Observable<any> {
    const dialogRef = this.dialog.open(ColumnVisibilityModal, {
        data: columns,
        autoFocus: false,
        hasBackdrop: true,
        disableClose: true
    });

    return dialogRef.afterClosed();
}

Когда я использую модал, открытый NGXS, после закрытия событие состояния не генерируется. После этого мне нужно где-то щелкнуть, чтобы вызвать функцию обратного вызова внутри функции openColumnModal.

Я использую диалог Angular Material.

Кто-нибудь знает, как автоматически вызывать функцию обратного вызова после закрытия модального режима?

Заранее спасибо:)

Ответы [ 3 ]

0 голосов
/ 18 июля 2019

Для добавления в anser Армена: Pipe используется для объединения различных функций и возвращает Observable. Tap используется в pipe для запуска побочного эффекта (например, запись значений между каналами для отладки и т. Д.).

Проверьте эту страницу документации RxJS , и вы можете прочитать:

Note: this is different to a subscribe on the Observable. If 
the Observable returned by tap is not subscribed, the side 
effects specified by the Observer will never happen. tap 
therefore simply spies on existing execution, it does not 
trigger an execution to happen like subscribe does.

Другими словами: если вы не подпишетесь на Observable , возвращаемую вашей трубой, канал вообще не будет работать. Ваше исправление:

return this.modalService.openColumnVisibilityModal(allCols).subscribe((result) => {
    ctx.setState({
        ...state,
        allColumns: result,
        userColumns: result.filter(col => col.visible)
    });
});
0 голосов
/ 22 июля 2019

PS - другие ответы, которые советуют подписываться внутри обработчика действий, неверны, так как NGXS не работает так!

Ваш текущий подход верен, проблема в том, что обработчики действий выполняются вне Angularзона.Просто внедрите класс NgZone в ваше состояние и выполните код в зоне Angular:

constructor(private modalService: ModalService, private zone: NgZone) {}

@Action(OpenColumnModal)
openColumnModal(ctx: StateContext<FeedStateModel>) {
  const state = ctx.getState();
  const allCols = state.allColumns;
  return this.zone.run(() =>
    this.modalService.openColumnVisibilityModal(allCols).pipe(
      tap(result => {
        ctx.setState({
          ...state,
          allColumns: result,
          userColumns: result.filter(col => col.visible)
        });
      })
    )
  );
}

Когда вы отправляете какое-либо действие - NGXS вызывает соответствующие обработчики для этого действия в родительской зоне, используя runOutsideAngular,это специально разработано.

Вы также можете посмотреть опцию executeStrategy , которая позволяет предоставить собственный класс или использовать существующий NoopNgxsExecutionStrategy, который вообще не использует класс NgZone.

0 голосов
/ 12 июля 2019

Попробуйте использовать подписку вместо трубы:

@Action(OpenColumnModal)
openColumnModal(ctx: StateContext<FeedStateModel>) {
    const state = ctx.getState();
    const allCols = state.allColumns;
    return this.modalService.openColumnVisibilityModal(allCols).subscribe(result => {
        ctx.setState({
            ...state,
            allColumns: result,
            userColumns: result.filter(col => col.visible)
        });
    })
}
...