У меня есть приложение с кнопкой «Экспорт». При нажатии приложение получает с сервера большой текстовый файл и использует API-интерфейс BLOB-объекта HTML5 для сохранения как, чтобы пользователь мог сохранить его на свой диск
, чтобы начать экспортную операцию отправки действие экспорта
this.store.dispatch(new scanListsActions.Export(id));
это действие затем обрабатывается кодом «эффектов», который отправляется на внутренний сервер для получения файла. по завершении отправляется действие ExportSuccess.
Теперь я не хочу хранить содержимое файла в хранилище, так как оно очень большое, с другой стороны, мне нужны данные в представлении для отправки это пользователю. в настоящее время вы можете видеть, что я отправляю его пользователю в коде редуктора (ниже).
Как обычно это делается? где находится место для отправки файла пользователю?
import * as fileSaver from 'file-saver'; // npm i --save file-saver
export function reducer(state: ScanListsState = initialState, action: ScanListsActions): ScanListsState {
switch (action.type) {
case ScanListsActionTypes.Export:
return {
...state,
loading: true
};
case ScanListsActionTypes.ExportSuccess:
// these 2 lines below send the file to the user (starts a download)
// where should i put this code. I don't think the reducer is the place for it
const blob = new Blob([action.payload.data], { type: 'text/plain; charset=utf-8' });
fileSaver.saveAs(blob, 'destination_list.txt');
return {
...state,
loading: false,
error: null
};
case ScanListsActionTypes.GeneralFail:
return {
...state,
loading: false,
error: action.payload
};
default:
return state;
}
}
Код эффектов
@Injectable()
export class ScanListsEffects {
constructor(private scanListService: ScanListService,
private actions$: Actions) { }
@Effect()
exportScanList$: Observable<Action> = this.actions$.pipe(
ofType(scanListsActions.ScanListsActionTypes.Export),
mergeMap((action: scanListsActions.Export) =>
this.scanListService.getScanList(action.payload).pipe(
map(sList => (new scanListsActions.ExportSuccess(sList))),
catchError(err => of(new scanListsActions.GeneralFail(err)))
)
)
);
}