使用异步管道从可观察对象中读取对象字段

Posted

技术标签:

【中文标题】使用异步管道从可观察对象中读取对象字段【英文标题】:Read object field from observable using async pipe 【发布时间】:2018-07-24 09:08:28 【问题描述】:

我想更好地了解何时在 Angular 中使用异步管道。

我喜欢通过简单地添加一个订阅数据的管道来让数据异步显示在视图中的想法。

但是,我只在网络请求或其他一些自定义 observable 中看到并正确应用了异步管道,其中包含数据数组或单个字段(如可观察字符串)。

例如:

假设我进行了一个返回大学生数组的 API 调用。

// This data is within a network response
$students = ...get...map... 
[
  
    name: "Bob OConnel",
    id: 0,
    description: "young..."
  ,
  
    name: "Rick Luckard",
    id: 3,
    description: "young..."
  ,
  
    name: "James Wing",
    id: 2,
    description: "young..."
  
]

这可以像这样显示在模板中:

<tr *ngFor="let student of $students | async">
  <td>student.id</td>
  <td>student.name</td>
  <td>student.description</td>
</tr>

但是,鉴于 ole REST API 理念。我还没有进行过只返回一组数据的生产 API 调用。始终存在与数据数组处于同一级别的字段。但它们的存在是有原因的,我不想简单地将那些额外的字段扔到 Mapping 中。

所以 $students 不是一个数组,而是:

// This data is within a network response
$students = ...get...map... 

  id: "69asdkasdkljasd6969"
  href: "someURLrepresentingTheDatasOrigins"
  length: 3
  items: [
    
      name: "Bob OConnel",
      id: 0,
      description: "young..."
    ,
    
      name: "Rick Luckard",
      id: 3,
      description: "young..."
    ,
    
      name: "James Wing",
      id: 2,
      description: "young..."
    
  ]

所以这意味着在模板中,我可以在 $students 可观察对象上抛出一个异步管道,但不能在其中的字段上。

这显然不起作用,因为可观察对象中的字段 是可观察的:

$students.id| async
// or
<tr *ngFor="let student of $students.items | async">...</tr>

那么,这是否意味着在这样的网络响应中,如果我想在模板中异步绑定到它们,我应该将响应的值映射到它们自己的单独的 observables 中?如果我不希望网络响应分成一百万个更小的对象(或者在我的示例中:id、length、href 和 items),有什么办法可以解决这个问题。

感觉好像我遗漏了一些关于使用 observables 的显而易见的东西,这些东西可以为我解决这个问题。如果我的问题不够清楚,请告诉我。

更新 我发现了一些我不知道我可以在这里做的事情:https://toddmotto.com/angular-ngif-async-pipe

对于应该使用某种加载指示器代替异步数据的情况非常有用。它还可以将订阅合并到一个地方。这将是一个偏好问题,但我认为在我的许多情况下,我更愿意将订阅放入 *ngIf。

除非您可以在 *ngFor.. 中执行相同的 else 模板逻辑?

【问题讨论】:

【参考方案1】:

您不需要将值映射到它们自己的单独的 observable 中。相反,您可以简单地将 observable 与 async 管道一起包装在括号中,然后到达 observable 返回的对象内的字段。

试试:

<tr *ngFor="let student of ($students | async).items">
  <td>student.id</td>
  <td>student.name</td>
  <td>student.description</td>
</tr>

【讨论】:

我认为这行不通。如果是这样,那很酷。但是,它不会导致订阅 $students 吗?如果我想在模板的其他地方执行此操作怎么办:($students | async).id。那么我不会订阅同一个 observable 两次吗? 正如@NikolaGavric 所说。它将订阅$students。但这有什么问题呢?你可以多次订阅同一个 Observable。 另一个好处是它也会自动处理退订

以上是关于使用异步管道从可观察对象中读取对象字段的主要内容,如果未能解决你的问题,请参考以下文章

如何使用来自html的异步管道获取可观察对象的嵌套值

从可观察对象返回的复杂对象中访问数据

当其他可观察对象为真时,从可观察对象中获取项目

无法从可观察对象中提取数据

我如何从可观察对象创建对象,该对象返回对象数组

如何强制视图刷新而不让它从可观察对象自动触发?