Angular 如何对表的行执行并发HTTP请求

Angular 如何对表的行执行并发HTTP请求,angular,Angular,我很难使用可观察对象和分布式API。我有一个包含许多行的表,对于每一行,我需要在单独的域服务上使用单独的API获取该行的“状态”。显而易见的解决方案是预先加载所有内容,如下所示: 我有10行,所以我将10个模型存储在一个数组中,如myArray:Model[]。然后,我可以订阅一个HTTP请求来获取这些模型,并将它们存储在这个数组中的组件上。在该请求返回后,我可以迭代每个模型,并执行另一个请求以获取每个模型的“状态”。这需要我1)将模型域模型类与状态属性进行卷积,然后对状态调用执行另一个。订阅,

我很难使用可观察对象和分布式API。我有一个包含许多行的表,对于每一行,我需要在单独的域服务上使用单独的API获取该行的“状态”。显而易见的解决方案是预先加载所有内容,如下所示:

我有10行,所以我将10个模型存储在一个数组中,如
myArray:Model[]
。然后,我可以订阅一个HTTP请求来获取这些模型,并将它们存储在这个数组中的组件上。在该请求返回后,我可以迭代每个
模型
,并执行另一个请求以获取每个模型的“状态”。这需要我1)将
模型
域模型类与
状态
属性进行卷积,然后对状态调用执行另一个
。订阅
,这将允许我为每个类设置
状态
属性。现在我终于可以渲染整个表了。或者2)我可以有第二个数组,比如
myStatuses:StatusModel[]
,它包含我所有
Model
的所有状态,然后在表中执行
getStatusForModel(Model)
,在运行时必须找到正确的状态

这感觉像是做一些相当简单的事情的大量代码

我本以为我不能通过使用可观察对象和异步管道来添加所有这些额外的状态。。。但是,当我尝试将异步管道与返回承诺的调用(如
getStatusAsync(model)
)一起使用时,我的浏览器会进入无限循环,因为它每次都返回承诺,而更改检测会迫使视图一次又一次地更新

基本上,我不知道执行异步操作的预期用途是什么,而不必在我的组件中保存这么多状态。如果我甚至不能返回实际的
Promise
,并且只能通过更改检测而不是Promise对象本身跟踪返回的值,那么
AsyncPipe
的意义何在


我觉得Angular中的Observables和async添加了比它应该添加的更多的代码和复杂性。我是做错了什么,还是这只是现在使用可观察和承诺的现实?

我对不得不使用如此繁琐的API表示同情

是的,如果您只需要在模板中使用异步管道,“展开”可观察对象是最容易的

是的,只要异步管道接收到不同的可观察实例,它就会重新订阅。这是因为angular无法知道新的可观察物与旧的等价

另一方面,在检测到更改的表达式中调用函数通常是不受欢迎的,因为该函数是在每次更改检测运行期间执行的(是的,即使参数没有更改;angular无法知道返回值仅取决于参数)

因此,您不应该在变更检测期间创建可观察的状态

也就是说,我会这样做

models = this.fetchModels().pipe(map(
  models => models.map(
    model => {...model, status: this.fetchStatus(model)}
  )
));
在模板中

<tr *ngFor="let model of models | async">
  <td>{{model.name}}</td>
  <td>{{model.status | async}}</td>
</tr>

{{model.name}
{{model.status}异步}
请注意,每当
模型在表中可见时,此解决方案将导致发出新的API请求。这可能比您想要的更频繁。您可以通过使用适当的rxjs操作符,或者通过在您的typescript代码中手动订阅可观察到的状态,来控制状态重新加载的频率

附录:这不是违反了DDD吗?

你问:

我不想这样做的原因是在适当的DDD中,您应该拥有彼此解耦的域对象

我不认为这是一个明确的结论:DDD存储库返回聚合,而不是单个实体

在真正的SOA中,我将在一个服务上使用Order API,在第二个服务上使用Invoice API。然后,我将从订单API获取订单列表,然后请求获取每个订单的发票。通常,我认为在UI上混合模型是不好的,这意味着当后端模型根本不这样做时,我不必强制使用Order.InvoiceStatus属性。这是耦合域模型

在DDD中,在每个有界上下文中都有一种无处不在的语言

你似乎认为你的UI和后端在相同的有界上下文中,但是如果是,为什么他们使用结构上不同的模型呢?为什么发票状态显示在订单表中,但存储在发票表中

在DDD中,ui和后端之间关于域结构的这种紧张关系可以通过两种方式解决:

  • 共享内核:UI和后端在一个通用模型上达成一致。模型已更改,因此适合所有人。在您的情况下,这意味着如果UI需要订单上的发票状态,后端应该返回订单上的发票状态

  • 反腐败层:UI和后端有不同的模型,模型通过边界时会被转换。也就是说,在API访问期间,域模型将转换为更适合UI的视图模型

您必须决定这些方法中哪一种更适合您的应用程序

我希望我能将这些分开,但听起来Angualr更希望这样做的方式是引入第三个模型,比如OrderViewModel,它可以处理订单和发票(可能还有其他模型)。你觉得对吗

从技术上讲,angular不关心数据模型的结构。它几乎可以绑定到任何东西


但从最佳实践的角度来看,我发现每一层都可以使用适合它的模型是很重要的。所以,是的,如果您不能使用共享内核,我建议您使用一个(轻量级)反腐败层。

我对必须工作表示同情