Angular NgRx:倾听服务中的状态变化,而不是使用效果

Angular NgRx:倾听服务中的状态变化,而不是使用效果,angular,ngrx,ngrx-effects,Angular,Ngrx,Ngrx Effects,我的问题是:服务能否侦听状态更改并基于状态值进行http调用,还是必须由效果(NgRx)触发? 因此,与通常在web上找到的示例中使用的效果调用服务不同,您可以让一个服务监听商店的某个部分并根据该部分做出反应。因此没有更多的影响。 我的问题更多的是一个哲学(最佳实践)问题,而不是一个技术问题,因为从技术上讲,两者都有效 更新 下面是一个具体的案例来理解我为什么要问: 背景: 我有一个从后端接收的元素列表。我可以过滤元素列表。一次可以有多个过滤器。过滤是在后端完成的 目前的执行情况: 组件分派一个

我的问题是:服务能否侦听状态更改并基于状态值进行http调用,还是必须由效果(NgRx)触发? 因此,与通常在web上找到的示例中使用的效果调用服务不同,您可以让一个服务监听商店的某个部分并根据该部分做出反应。因此没有更多的影响。 我的问题更多的是一个哲学(最佳实践)问题,而不是一个技术问题,因为从技术上讲,两者都有效

更新

下面是一个具体的案例来理解我为什么要问:

背景:

我有一个从后端接收的元素列表。我可以过滤元素列表。一次可以有多个过滤器。过滤是在后端完成的

目前的执行情况:

组件分派一个
过滤器元素
操作。该操作由调用http服务的效果拾取。该服务要求后端提供基于筛选器的元素列表。 因为可以有多个过滤器,所以效果(或服务)需要知道当前的过滤器是什么,并将新的过滤器添加到该列表中。因此,我在效果中添加了一个
.withLatestFrom(this.state$)
,并从中获取当前过滤器列表

问题:

问题是状态没有用新过滤器更新。我可以捕获reducer中的
FILTER\u元素
操作并更新状态,但这会导致其他一些潜在问题。 将首先调用哪个效果和减速器? 如果出现后端错误怎么办?我的状态将使用新筛选器更新,但列表未被筛选。 异步性呢?如果在服务器应答之前或在状态更新之前请求另一个筛选器,该怎么办

这对我来说似乎有点太乱了

所以我的问题是: 商店真的是真相的唯一来源吗?而不仅仅是一个“日志”的发生,这可能是或可能不是最新的。我的意思是,想要添加过滤器的组件可以通过调度一个
add\u filter
操作来实现,该操作将更新状态中的过滤器列表。我的服务可以监听过滤器列表,并在每次列表更改时调用后端。 因此,该服务只在状态改变时调用后端,我们知道它是最新的真实状态。然后将“成功”操作与更新的列表一起发送到商店。 我不认为这会产生比效果更多的潜在无限循环。。。毕竟,这些影响也会导致无限循环。。。
因此,我的服务实际上是一种监听存储更改而不是直接监听操作的效果。

您不应该这样做,因为它明显违反了单向数据流。异步事件会导致操作进入更新存储区,从存储区出来的数据不会触发新的异步事件,而新的异步事件又可能触发新的操作。这可能会产生严重的bug,比如无限事件循环,并且使应用程序难以推理。由于这个原因,特效服务存在,以确保不会违反单向数据流

使用ngrx时必须记住,一个动作代表整个应用程序状态的变化,即完全停止。特效服务本质上采取了一个需要一些远程资源来描述完整状态更改的操作,并获取该远程资源,并将其映射到一个新的操作中,该操作在完全状态更改到达存储之前就表示完整状态更改。如果您正在根据商店中的内容进行进一步的状态更改,那么很明显,您没有在操作中完整描述您的状态更改

实际上进入存储的操作的重播每次都应该产生相同的状态,同样,如果您根据从存储中获得的内容进行其他状态更改,则不会出现这种情况

编辑以解决其他问题:

存储是设计上的唯一真实来源,也就是说,应用程序的状态不经过存储就不会更新。作为开发人员,您有责任强制执行此操作。它不应该是你追溯更新它来反映“发生了什么”,它应该是实际的变化,存储是存储您的应用程序的状态

目前看来,您似乎想要过滤元素,然后通过发送UPDATE_FILTERS操作对接收到这些元素做出反应,这是100%错误的做法

解决问题的第一步是确保您的操作包含状态更改所需的所有信息,因此,如果您的效果服务需要访问当前状态,则说明您做错了。FILTER_ELEMENTS操作应该包含所有需要的过滤器,而effects服务不应该访问当前状态

下一步是再次确保您的操作包含状态更改所需的所有信息。不要在reducer中捕获FITLER_元素,映射到一个新动作中,包含过滤元素和过滤器的元素FITLER__________,并对其作出反应,并在同一动作中应用这两个状态更改。在发生错误的情况下,您将捕获该错误,并使用创建该状态所需的数据映射到FILTER_error操作中,其中可能包括旧的筛选器。对于在旧过滤器完成之前通过的新过滤器,则使用switchMap确保查看最新的过滤器,并忽略以前的请求


所有这些在框架中都是可以解决的,并且您的效果服务不应该能够导致无限循环,如果可以的话,您的设计是错误的,很可能是试图访问效果服务中的状态。但你永远不应该用新的行动来回应行动。

谢谢你的回答。这是有道理的,但我仍然很难理解如何在我的案例中正确使用ngrx。我起床了