Angular - 调度动作时出现“TypeError:无法冻结”
Posted
技术标签:
【中文标题】Angular - 调度动作时出现“TypeError:无法冻结”【英文标题】:Angular - "TypeError: Cannot freeze" when dispatching an action 【发布时间】:2019-02-27 20:23:35 【问题描述】:我正在开发一个使用 ngrx 商店和效果的 Angular 应用程序。我明白了
“类型错误:无法冻结”
从我的组件调度操作时出错。我为文件上传功能编写了它。我认为我正在改变状态,但无法弄清楚在哪里以及如何解决它。 这是我的详细代码:
Actions:
export enum FileUploadActionTypes
UploadFile = '[File Upload] Upload File',
UploadFileSuccess = '[File Upload] Upload File Success',
UploadFileFailure = '[File Upload] Upload File Failure'
export class UploadFile implements Action
readonly type = FileUploadActionTypes.UploadFile;
constructor(public payload: any)
export class UploadFileSuccess implements Action
readonly type = FileUploadActionTypes.UploadFileSuccess;
constructor(public payload: any)
export class UploadFileFailure implements Action
readonly type = FileUploadActionTypes.UploadFileFailure;
constructor(public payload: any)
export type FileUploadActionsUnion = UploadFile | UploadFileSuccess | UploadFileFailure;
Service:
export class FileUploadService
constructor(private httpClient: HttpClient)
uploadFile(file: any): Observable<any>
return this.httpClient.post<any[]>('/api-url/', file);
Effect:
@Effect()
uploadFile$ = this.actions$.pipe(
ofType<UploadFile>(FileUploadActionTypes.UploadFile),
mergeMap(action => this.fileUploadService.uploadFile(action.payload).pipe(
map(result => new UploadFileSuccess(result)),
catchError(error => of(new UploadFileFailure(error)))
))
)
Reducer:
export interface State
fileUploadSuccessResponse: any,
fileUploadFailureResponse: any
export const initialState =
fileUploadSuccessResponse: null,
fileUploadFailureResponse: null
export const getFileUploadSuccessResponse = state => state.fileUploadSuccessResponse;
export const getFileUploadFailureResponse = state => state.fileUploadFailureResponse;
export function reducer(state: State = initialState, action: FileUploadActionsUnion):State
switch(action.type)
case FileUploadActionTypes.UploadFile:
return
...state
case FileUploadActionTypes.UploadFileSuccess:
return
...state,
fileUploadSuccessResponse: action.payload
case FileUploadActionTypes.UploadFileFailure:
return
...state,
fileUploadFailureResponse: action.payload
default:
return state;
【问题讨论】:
payload 长什么样子? 【参考方案1】:看来您正在使用ngrx-store-freeze
npm 包。此软件包可确保您对商店所做的任何更新都不会直接发生变化。此过程的一部分是将Object.freeze()
应用于您尝试调度的操作的payload
对象。即this.store.dispatch(new UploadFiles(file))
。
<input type="file">
控件的默认行为是将其值保存为FileList
对象。因为此对象是原始数据类型,javascript 会将其视为只读,从而阻止您写入它的属性。这也解释了为什么 Object.freeze()
会失败,因为它无法对只读数据类型应用冻结。
我最近在使用 NGRX 和 <input type="file">
表单控件时遇到了同样的问题。解决方法是在分派到商店之前将 FileList
克隆到一个新对象中。
onChange(control: FormControl)
const primitiveFileList: FileList = control.value;
const clonedFiles = ...primitiveFileList ;
this.store.dispatch(new UploadFiles(clonedFiles));
如果其他人知道这种方法的任何潜在缺陷,我将不胜感激。
【讨论】:
在我的例子中,只是克隆 FileList 对象删除了length
属性和item()
函数。所以我需要自己给clone加上length属性,以后还要用[i]
代替item(i)
。以上是关于Angular - 调度动作时出现“TypeError:无法冻结”的主要内容,如果未能解决你的问题,请参考以下文章
使用 Angular 材质定义自定义主题时出现 SassError
为啥在尝试升级 Angular 时出现“没有导出成员”错误?