angular - 将状态转换为其他对象的 NGRX 选择器会导致 ExpressionHasChanged 异常
问题描述
在这个讨论之后,我们进入并更改了我们的选择器以返回“丰富”的对象。因此,我们的 NGRX 实体状态包含基本的 JavaScript 对象,但我们有返回丰富对象的状态选择器。
我们选择器中的相关代码片段:
const getAllAssets = createSelector(
getAssetsState,
getAllAssetModels,
(state: AssetsState, assets) => {
// if we just return assets, no error occurs(!)
return assets.map(a => createAsset(a));
}
);
在组件 HTML 中:
<ab-assets
data-test-id="data-filter"
[assets]="assets$ | async"></ab-assets>
和组件 TS:
assets$: Observable<Asset[]>;
...
ngOnInit() {
this.assets$ = this.store.pipe(
select(AssetsSelectors.assetsQuery.getAllAssets)
);
}
这一切都很好,但我们得到了著名的 ExpressionChangedAfterItHasBeenCheckedError。
ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has
changed after it was checked. Previous value: 'allData: [object Object]'.
Current value: 'allData: [object Object],[object Object],[object Object],
[object Object],[object Object],[object Object]'.
.map() 函数似乎是问题所在,当我只返回资产数组时它工作正常。
@timdeschryver 在本主题中以非常相似的方法进行了回复,所以我不确定为什么它不起作用?
但是,当我不创建新数组而是修改现有数组时,它可以正常工作:
for (let i = 0; i < assets.length; i++) {
assets[i] = createAsset(assets[i]);
}
return assets;
所以关键问题是:为什么当我返回一个新数组时会出现 ExpressionHasChanged 错误?
解决方案
问题不在于 .map(),而是我也在检索选择器中的状态这一事实。
所以,这有效:
const getAllAssets = createSelector(
getAllAssetModels, assets => {
return assets.map(a => createAsset(a));
});
这不起作用:
const getAllAssets = createSelector(
getAssetsState,
getAllAssetModels, (state, assets) => {
return assets.map(a => createAsset(a));
});
还是觉得不对劲。。。
推荐阅读
- python - Django - 使用 PIL 在保存方法中动态调整图像大小和创建缩略图
- php - 找不到命令 cim。Drush 无法查询数据库
- python - 我有一个包含 100 个元素的列表,我想使用 import csv 将其制成 excel 中的 10x10 表格
- javascript - 控制台不会记录 div 数组
- java - 无法初始化代理 - 没有会话,在 Spring 拦截器内
- sql - 使用 ComboBox 和 LIKE 语句根据另一列填充 MS-Access 表
- android - 如何打包 PagedList<>?
- angularjs - AngularJS $location.path 在桌面上工作但在移动设备上不工作
- ios - 错误 - 电子邮件地址格式错误。Xcode Swift Firebase
- javascript - 如何用material-ui设置时钟(timePicker)的颜色?