调度动作Ngrx

如何解决调度动作Ngrx

我的用户可以将产品添加到列表中,并且我想为进入列表的每个产品生成一个ID(ID:1,ID:2,ID:3 ....)。 这是我的代码:

减速器:

export const productReducer = createReducer(
initialSate,on(addProductToList,(state,action) => {
    console.log(state)
    return {
        ...state,productList: [...state.productList,action]
    }
}))

操作:

export const addProductToList = createAction(
"[Product] Add Product To List",props<{ product: Product; }>()
);

选择器:

export const selectFeature = (state: any) => state;

export const selectFeatureCount = createSelector(
selectFeature,(state: any) => state.products.idCounter
);

ONCLICK功能:

onSubmit(e) {
  e.preventDefault();

  if (this.addProductForm.valid)
  {
    this.store.pipe(select(selectFeatureCount)).subscribe(res => {
      this.addProductForm.value.id = res;
      this.addProductForm.value.isRecieved = false;
      this.store.dispatch(addProductToList(this.addProductForm.value));
      this.addProductForm.reset(this.addProductForm)
      this.router.navigate(['/products']);
    })
  }
}

解决方法

在您发表评论后,我想我理解您的问题背后的原因。

以下是我可以向您建议的解决方案:

简单

因此,如果您只想标识productList内的项目,则可以使用数组的索引,因此,如果您有一些简单的用例,例如使用{{1 }}后,您就可以在单个页面上呈现项目了

*ngFor

因此会发生的事情(如果您使用的是ngFor的默认行为,而没有使用<div *ngFor="let product of products; let i = index"> <div>{{product....}} </div> <button (click)="delete(i)">Delete</button> <button (click)="edit(i)">Edit</button> </div>选项)是,每当您修改产品列表时,元素就会重新呈现,并带有来自商店,您将能够一次又一次地编辑/修改新的(修改过的)产品列表。

在减速器内部,您将看到类似以下的内容

trackBy

稍微复杂一点

假设您有某种更复杂的视图,其中您在多个位置显示产品列表中的相同产品元素,并且数组idx与实际产品元素之间的动态关系可能会使您的代码混乱(它是动态的,因为无论何时您从数组中删除元素,索引比已删除元素高的元素将其索引减1,换句话说,将在数组内向左移动一个位置)

在这种情况下,我将建议为每个新产品创建某种唯一的ID,例如,它可能是基于时间的ID(您也可以使用Math.random或任何类似的方式),就像下面的代码片段一样。

export const productReducer = createReducer(
initialSate,on(addProductToList,(state,action) => {
    return {
        ...state,productList: [...state.productList,action]
    }
}),on(deleteProduct,{idx}) => {
    return {
        ...state,productList: [...state.productList.slice(0,idx),...state.productList.slice(idx+1)]
    }
}),{idx,modifiedProduct}) => {
    return {
        ...state,productList: [
        ...state.productList.slice(0,modifiedProduct,...state.productList.slice(idx+1)
        ]
    }
}),)

这样做,您将保证自己不会做任何有趣的事情,只要您是该产品列表的唯一消费者(更多有关以后可能出现的问题)。

在化简器内部,您可以使用相同的方法,但是从一开始,我们就需要自己找到它,而不是拥有元素的索引,这没什么大不了的。 (您可以查看{ id: Date.now(),productName: 'Whatever the products is called',productPrice: 'Whatever the price is',... }

推荐的解决方案

因此,按照我前面提到的方法,可能发生的问题很少,这些问题与id-s的唯一性有关,假设我们使用Array.findIndex()方法在以下位置创建了多个产品同时,我们有机会创建具有相同ID的多个实例,这将使事情变得很糟(假设您要删除带有Date.now()的元素,但是有两个具有该ID的元素,一个应该删除?)。 简单的解决方法是以一种更智能的方式创建我们的id或使用一些库为我们完成此操作,并且该解决方案将在99.9%以上的情况下正常工作。

但是,发生这种重复的更为现实的情况有些不同,可以说有人故意生成具有现有ID的新产品并将该产品发送给您的BE ...您可以猜测会发生什么。

因此,我建议您做的是在创建新实体时,向BE发送请求,让其处理整个id生成的东西,然后根据需要在前端中使用该唯一id,这样可以保证不会发生重复。

要使此流程正常运行,您还必须仔细研究id=x

结论

最佳实践取决于用例,如果您正在做某种小型的辅助项目,而第二种解决方案则是如果您要进行的工作将要在生产中使用并且被客户使用,请不要让任何偶然的事情发生,寻求第三个解决方案。

**旁注:如果您对更高级的@ngrx/effects使用感兴趣,请务必查看ngrx

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-