我用的是ngrx。我想显示文件上传进度。
此时我有文件正在上传,但是没有显示上传进度
我也得到一个错误:
错误:效果“FileEffects.uploadFile$”发送了一个无效的动作: 未定义
如何解决?我做错了什么?
html:
<div *ngIf="(isInProgress$ | async)">
<div *ngIf="progress$ | async as progress">
<mat-progress-bar [value]="progress"></mat-progress-bar>
</div>
</div>
ts:
progress$: Observable<number> = EMPTY;
isInProgress$: Observable<boolean> = EMPTY;`
ngOnInit(): void {
this.progress$ = this.store$.pipe(
select(selectUploadFileProgress)
);
this.isInProgress$ = this.store$.pipe(
select(selectUploadFileInProgress)
);
}
动作:
export const UPLOAD_PROGRESS = '[File Upload API] Progress';
export const uploadProgress = createAction(UPLOAD_PROGRESS, props<{ progress: any }>());
效果:
uploadFile$ = createEffect(() => {
return this.actions$.pipe(
ofType(uploadFile),
switchMap((action) => {
return this.fileService.uploadFile(action.files, action.parent).pipe(
map((event) => {
if (event.type === HttpEventType.UploadProgress) {
return uploadProgress({
progress: Math.round((100 * event.loaded) / event.total!),
});
} else if (event instanceof HttpResponse) {
return uploadFileSuccess({ file: event.body });
}
}),
catchError((err) => {
return of(err);
})
);
})
)
});
减速器:
const fileReducer = createReducer(
initialState,
on(uploadProgress, (state, action) => {
return {
...state,
progress: action.progress
};
})
);
选择器:
export const FILE_STATE_NAME = 'files';
export const selectFileState: MemoizedSelector<
object,
FileState
> = createFeatureSelector<FileState>(FILE_STATE_NAME);
export const fileSelectors = fileAdapter.getSelectors();
export const selectFile = createSelector(
selectFileState,
fileSelectors.selectAll
);
const getProgress = (state: FileState): number => state.progress;
const getInProgress = (state: FileState): boolean =>
state.status === UploadStatus.Started && state.progress >= 0;
export const selectUploadFileProgress: MemoizedSelector<
object,
number
> = createSelector(
selectFileState,
getProgress
);
export const selectUploadFileInProgress: MemoizedSelector<
object,
boolean
> = createSelector(
selectFileState,
getInProgress
);
不要忘记在 HttpClient 中设置属性:
const req = new HttpRequest('POST', '/upload/file', file, {
reportProgress: true
});
或者这个
uploadFile(file: any): Observable<HttpEvent<any>>{
return this.http.post(this.url , app, {
reportProgress: true, observe: "events", headers: new HttpHeaders(
{ 'Content-Type': 'application/json' },
)
});
}
resportProgress
很重要!