ngrx/store 使用带有 class 的 createFeatureSelector 时抛出 运行 时间错误
ngrx/store throws run time error when using createFeatureSelector with a class
我的应用程序是基于 Angular、Immutable.js、NgRx 的最新版本构建的;
我想利用 NGRX 的 createFeatureSelector
和 createSelector
。但是,我好像只能select 件的存储按字符串。我已经提取了相关的代码片段(我认为)。我还在下面添加了一个 plunker link 来说明这个问题。
当应用程序启动时,它会抛出 Uncaught TypeError: <CLASS> is not a constructor
的错误。
我尝试过的方法和产生的症状:
如果我将有问题的文件移到 initialState 文件中,reducer 将在该文件中获得默认状态,错误将移动到构造链下的下一个 class。在下面的示例中,CopyRollbackState
(下面的代码)是一个 class,它包含两个子 classes CopyRollbackRemovables$
和 CopyRollbackConfirm$
;如果我将第一个复制到 initialState 文件中,错误将移动到第二个。
如果我用不可变映射替换顶层 class、CopyRollbackState
,应用程序无法 运行 并出现相同的错误。
如果我从我的状态初始化中删除所有硬 classes,例如使用 immutable.fromJS()
方法,错误消失。但是,我想在商店中使用实际的 classes。
感谢您的帮助。
例如
/** provider.ts */
// this works
this.copyRollbackRemovables$ = this._store.select('copyRollbackRemovables');
// this fails with the below error
// this is one of the methods of ngrx i want to use !!
this.copyRollbackRemovables$ = this._store.pipe(select(_RootReducer.getRollbackRemovables));
_
/** _RootReducer.ts */
export const appState: ActionReducerMap<AppState> = {
...
copyRollbackRemovables: fromCopyRollback.copyRollbackEntitiesReducer,
...
}
export const getRollbackRemovables =
createFeatureSelector<CopyRollbackRemovables$>('copyRollbackRemovables');
_
/** fromCopyRollback.ts reducer */
export function copyRollbackEntitiesReducer(
state: any = initialState.get('copyRollbackEntities'),
action: Action
): CopyRollbackRemovables$ {
switch (action.type) {
default:
break;
}
return state;
}
_
/** model.ts */
const copyRollbackStateRecord = Record({
copyRollbackEntities: null,
copyRollBackConfirm: null,
});
interface ICopyRollbackState {
copyRollbackEntities: CRM.ICopyRollbackRemovables$,
copyRollBackConfirm: CRM.ICopyRollbackConfirm$
}
export class CopyRollbackState extends copyRollbackStateRecord implements ICopyRollbackState {
copyRollbackEntities: CRM.CopyRollbackRemovables$;
copyRollBackConfirm: CRM.CopyRollbackConfirm$;
constructor(config: ICopyRollbackState) {
super(Object.assign({}, config, {
copyRollbackEntities: config.copyRollbackEntities && new CRM.CopyRollbackRemovables$(config.copyRollbackEntities),
copyRollBackConfirm: config.copyRollBackConfirm && new CRM.CopyRollbackConfirm$(config.copyRollBackConfirm)
}));
};
}
export const initialState: CopyRollbackState = new CopyRollbackState({
copyRollbackEntities: {
meta: {
loading: false
},
byBatchId: Map({})
},
copyRollBackConfirm: {
meta: {
loading: false
},
data: {
templateItemIds: [],
rollBackConfirmer: false,
rollBackReason: ''
}
}
});
// CRM.ts, similar extend and interface as above class
export class CopyRollbackRemovables$ extends copyRollbackRemovablesRecord$ implements ICopyRollbackRemovables$ {
meta: IPagedMeta;
byBatchId: Map<string, List<CopyRollback>>;
constructor(config: ICopyRollbackRemovables$) {
super(Object.assign({}, config, {
meta: config.meta && new PagedMeta(config.meta),
byBatchId: config.byBatchId && Map(config.byBatchId)
}));
}
}
这是错误中引用的转译代码。
var CopyRollbackState = (function (_super) {
__extends(CopyRollbackState, _super);
function CopyRollbackState(config) {
return _super.call(this, Object.assign({}, config, {
copyRollbackEntities: config.copyRollbackEntities && new CRM.CopyRollbackRemovables$(config.copyRollbackEntities),
copyRollBackConfirm: config.copyRollBackConfirm && new CRM.CopyRollbackConfirm$(config.copyRollBackConfirm)
})) || this;
}
;
return CopyRollbackState;
}(copyRollbackStateRecord));
我构建了一个 bare minimum Plunker 来显示错误。当 plunk 加载时,您可以在控制台中看到错误。对于我的应用程序,该错误会阻止应用程序加载。
我解决这个问题的方法是将所有 Class
定义移动到一个文件中。在我的例子中,我在 *.store.ts 文件中有 class 定义,它依赖于 *.model.ts 文件中的 class 定义。将所有定义移动到两者之一解决了这个问题。
仍然不确定实际问题出在哪里。也许 DI 很难找到正确的 class.
我的应用程序是基于 Angular、Immutable.js、NgRx 的最新版本构建的;
我想利用 NGRX 的 createFeatureSelector
和 createSelector
。但是,我好像只能select 件的存储按字符串。我已经提取了相关的代码片段(我认为)。我还在下面添加了一个 plunker link 来说明这个问题。
当应用程序启动时,它会抛出 Uncaught TypeError: <CLASS> is not a constructor
的错误。
我尝试过的方法和产生的症状:
如果我将有问题的文件移到 initialState 文件中,reducer 将在该文件中获得默认状态,错误将移动到构造链下的下一个 class。在下面的示例中,
CopyRollbackState
(下面的代码)是一个 class,它包含两个子 classesCopyRollbackRemovables$
和CopyRollbackConfirm$
;如果我将第一个复制到 initialState 文件中,错误将移动到第二个。如果我用不可变映射替换顶层 class、
CopyRollbackState
,应用程序无法 运行 并出现相同的错误。如果我从我的状态初始化中删除所有硬 classes,例如使用
immutable.fromJS()
方法,错误消失。但是,我想在商店中使用实际的 classes。
感谢您的帮助。
例如
/** provider.ts */
// this works
this.copyRollbackRemovables$ = this._store.select('copyRollbackRemovables');
// this fails with the below error
// this is one of the methods of ngrx i want to use !!
this.copyRollbackRemovables$ = this._store.pipe(select(_RootReducer.getRollbackRemovables));
_
/** _RootReducer.ts */
export const appState: ActionReducerMap<AppState> = {
...
copyRollbackRemovables: fromCopyRollback.copyRollbackEntitiesReducer,
...
}
export const getRollbackRemovables =
createFeatureSelector<CopyRollbackRemovables$>('copyRollbackRemovables');
_
/** fromCopyRollback.ts reducer */
export function copyRollbackEntitiesReducer(
state: any = initialState.get('copyRollbackEntities'),
action: Action
): CopyRollbackRemovables$ {
switch (action.type) {
default:
break;
}
return state;
}
_
/** model.ts */
const copyRollbackStateRecord = Record({
copyRollbackEntities: null,
copyRollBackConfirm: null,
});
interface ICopyRollbackState {
copyRollbackEntities: CRM.ICopyRollbackRemovables$,
copyRollBackConfirm: CRM.ICopyRollbackConfirm$
}
export class CopyRollbackState extends copyRollbackStateRecord implements ICopyRollbackState {
copyRollbackEntities: CRM.CopyRollbackRemovables$;
copyRollBackConfirm: CRM.CopyRollbackConfirm$;
constructor(config: ICopyRollbackState) {
super(Object.assign({}, config, {
copyRollbackEntities: config.copyRollbackEntities && new CRM.CopyRollbackRemovables$(config.copyRollbackEntities),
copyRollBackConfirm: config.copyRollBackConfirm && new CRM.CopyRollbackConfirm$(config.copyRollBackConfirm)
}));
};
}
export const initialState: CopyRollbackState = new CopyRollbackState({
copyRollbackEntities: {
meta: {
loading: false
},
byBatchId: Map({})
},
copyRollBackConfirm: {
meta: {
loading: false
},
data: {
templateItemIds: [],
rollBackConfirmer: false,
rollBackReason: ''
}
}
});
// CRM.ts, similar extend and interface as above class
export class CopyRollbackRemovables$ extends copyRollbackRemovablesRecord$ implements ICopyRollbackRemovables$ {
meta: IPagedMeta;
byBatchId: Map<string, List<CopyRollback>>;
constructor(config: ICopyRollbackRemovables$) {
super(Object.assign({}, config, {
meta: config.meta && new PagedMeta(config.meta),
byBatchId: config.byBatchId && Map(config.byBatchId)
}));
}
}
var CopyRollbackState = (function (_super) {
__extends(CopyRollbackState, _super);
function CopyRollbackState(config) {
return _super.call(this, Object.assign({}, config, {
copyRollbackEntities: config.copyRollbackEntities && new CRM.CopyRollbackRemovables$(config.copyRollbackEntities),
copyRollBackConfirm: config.copyRollBackConfirm && new CRM.CopyRollbackConfirm$(config.copyRollBackConfirm)
})) || this;
}
;
return CopyRollbackState;
}(copyRollbackStateRecord));
我构建了一个 bare minimum Plunker 来显示错误。当 plunk 加载时,您可以在控制台中看到错误。对于我的应用程序,该错误会阻止应用程序加载。
我解决这个问题的方法是将所有 Class
定义移动到一个文件中。在我的例子中,我在 *.store.ts 文件中有 class 定义,它依赖于 *.model.ts 文件中的 class 定义。将所有定义移动到两者之一解决了这个问题。
仍然不确定实际问题出在哪里。也许 DI 很难找到正确的 class.