如何在 RxJS observable 中添加额外的字段并等待它完成?

2023-12-03

我有一个返回的可观察值items,我只需要一个特定的项目,并且我想从也可观察到的 http 请求向其添加一些额外的字段。下面的代码是我试图实现这一目标的方法,但它不起作用。我需要完成所有可观察量才能获取完整的项目数据ngOnInit。我缺少什么?

ngOnInit() {
    myItemsObservable$(this.store, items, items.data)
        .map(items => items.find(
            item => {
                return item.id === id
            }
        ))
        .concatMap(item => {
            return this.apiService.get(`/items/${item.id}/extradata`).map(extra => ({
                ...item,
                extra
            }))
        })
        .subscribe(item => {
            // I expect item to have extra fields here.
            this.item = item
        })

        // this.item here should already be complete.
}


让我们看一下代码的简化版本:

1  function ngOnInit() {
2    myItemsObservable$().subscribe(item => this.item = item);
3    console.log(this.item); // undefined
4  }

您本质上是在调用两个立即执行的函数。

第 2 行创建一个订阅对象,该对象启动可观察对象内的数据流。但是...在第 2 行之后执行并没有暂停。因此,在可观察对象内的异步任务完成之前,将执行第 3 行。这就是为什么this.item还是undefined在第 3 行。

希望您能明白为什么您的评论不正确:

// this.item here should already be complete.

您正在传递一个函数(item => this.item = item)到subscribe()当可观察到的排放发生时对其进行处理的方法。这是代码中实际具有发出值的位置。

所以,如果我们移动console.log()在订阅内,this.item将不再是未定义的:

1  function ngOnInit() {
2    myItemsObservable$().subscribe(item => {
3      this.item = item;
4      console.log(this.item); // not undefined :-)
5    });
6  }

要解决您问题的两个部分:

如何在 RxJS observable 中添加额外字段

你已经在这样做了。您已经使用过map and concatMap运算符将源可观察值发出的值修改为您想要的值。

...然后等待它完成?

好吧,你本身并不“等待”它。使用 RxJS,您可以定义数据流动的行为。您可以访问实际数据的唯一位置是订阅内部。

但是...您可以直接在代码的其他部分直接引用可观察量,而不是订阅,然后将数据从可观察量复制到另一个变量。

让我们将代码分成几个不同的部分,以便更容易地了解如何在不订阅的情况下引用不同的可观察源:

id$ = this.route.paramMap.pipe(  // This could come from a form control input
    params => params.get('id')   // or some other observable source.
);

allItems$ = myItemsObservable$(this.store, items, items.data);

getItem$(id) {
  return this.allItems$.pipe(
    map(items => items.find(i.id === id))
  );
}

getExtraData$(id) {
  return this.apiService.get(`/items/${id}/extradata`);
}

item$ = this.id$.pipe(
    switchMap(id => getItem$(id)),
    switchMap(item => this.getExtraData(item.id).pipe(
      map(extra => ({ ...item, ...extra }))
    ))
  );
}

看看如何定义item$开始于id$?这意味着每当id$发出新的值,item$会自动调用getItem$(), then getExtraData()然后发出这个新项目。我们不需要订阅就能实现这一点。

我们可以简单地定义一个可观察量以开始另一个可观察量.pipe()排放量并对其进行改造以满足我们的需求。

我们本质上设计了一个可观察的对象,只要商店中的商品发生变化,或者每当我们选择的商品发生变化时,它都会发出id$发出一个新的值。从某种意义上说,我们已经建立了item$代表我们的item并且它始终是最新的,包括附加“额外数据”。这是非常强大的。现在我们就可以使用它了。

注意以下的定义item$不需要在ngOnInit;它实际上可以直接连接到您的组件。

确实我们可以在我们的组件中订阅......但我们通常可以只使用AsyncPipe在模板中:

<div *ngIf="item$ | async as item">
  <h1>{{ item.name }}</h1>
  <ul>
    <li>{{ item.description  }}</li>
    <li>{{ item.someProperty }}</li>
  </ul>
</div>

如果您发现自己经常在组件中订阅,只是将数据复制到局部变量,只是为了供模板使用;我鼓励你停下来问问自己这真的有必要吗?大多数时候,您可以定义一个可观察的对象,它可以准确地发出您的视图所需的数据,而无需订阅。

RxJS 提供了许多运算符和静态函数,可以轻松创建具有各种常见行为的可观察对象。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 RxJS observable 中添加额外的字段并等待它完成? 的相关文章

  • ReferenceError:regeneratorRuntime未定义(但在范围内工作)

    我遇到过这种奇怪的情况 ReferenceError regeneratorRuntime is not defined 我已经设法在一个非常小的设置中重现 与同一问题上的类似问题相比 并且还注意到一些奇怪的行为 具体取决于是否使用范围 以
  • 如何使用 JavaScript 创建链接?

    我有一个标题字符串和一个链接字符串 我不知道如何将两者放在一起以使用 JavaScript 在页面上创建链接 任何帮助表示赞赏 我试图解决这个问题的原因是因为我有一个 RSS 源并且有一个标题和 URL 列表 我想将标题链接到 URL 以使
  • Chart.js 在初始化时设置活动段

    我正在使用 Chart js v2 并且尝试在加载图表时模拟圆环图上某个段的 悬停状态 因此看起来有一个部分已突出显示 我已经搜索和梳理了代码一天 但找不到一个好的方法来做到这一点 提前致谢 设置片段的悬停样式有点令人困惑 因为它没有真正记
  • 渲染货币和符号并与来自不同单元格的数据相结合

    我正在使用最新的 jQuery DataTables v1 10 7 我正在尝试将数字解析为以下格式 239 90 USD 我可以使用此命令使货币正常工作 columns data Price render fn dataTable ren
  • 为什么 iife 在一个简单的例子中不起作用?

    我不明白为什么函数表达式调用不起作用并抛出错误 你能给我解释一下吗 var a function x alert x function a 1 谢谢大家 任务比我想象的要容易得多 这是因为 JS 将 IIFE 解析为函数的参数调用 这样做时
  • IE从哪个版本开始支持Object.create(null)?

    您可以通过多种方式在 JavaScript 中创建对象 creates an object which makes the Object prototype of data var data1 new Object Object liter
  • 图像无法在带有 DOM 的 IE 中加载:控制台中的 7009 错误(无法解码)

    当在 IE 中的单个页面上加载许多图像时 在 IE11 中重现 其中一些图像开始加载失败 并在控制台中出现类似以下警告的内容 DOM7009 无法解码 URL 处的图像 某些唯一的 url 当我查看网络流量时 似乎确实从服务器收到了每个图像
  • 使用 dc.js 按条形值对条形图中的条形进行排序(排序)

    如何通过维度的计算值而不是维度本身的名称对 dc js 示例中的 x 轴 维度 进行排序 例如 请考虑序数条形图的 dc js 示例 https github com dc js dc js blob master web examples
  • 在打字稿中导入 json

    我是 typescript 的新手 在我的项目中 我们使用 typescript2 在我的要求之一中 我需要导入 json 文件 所以我创建了 d ts 文件如下 test d ts declare module json const va
  • 防止 iOS 键盘在 cordova 3.5 中滚动页面

    我正在使用 Cordova 3 5 和 jQuery mobile 构建 iOS 应用程序 我在大部分应用程序中禁用了滚动功能 但是 当我选择输入字段时 iOS 键盘会打开并向上滚动页面 我不想要这个功能 由于输入足够高 键盘不会覆盖它 我
  • 尝试将数据存储在点击器网站中

    我正在尝试存储一个名为的变量score无论何时刷新 您都会一次又一次地使用它 我不明白的是它的代码是什么 我尝试了一些方法 但似乎都不起作用 这是我的答题器网站 但是当我尝试使用 JavaScript 来存储它时 它不起作用window o
  • Javascript split 不是一个函数

    嘿朋友们 我正在使用 javascript sdk 通过 jQuery facebook 多朋友选择器在用户朋友墙上发布信息 但是我收到此错误friendId split 不是函数 这是我的代码 function recommendToFr
  • 刷新页面时保存用户的选择

    我目前有一个页面显示不同团队的数据 我有一些数据 用户可以单击使其处于 打开 或 关闭 状态 并为每个数据显示不同的图标 它基本上就像一个清单 只是没有物理复选框 我想记住哪些 复选框 已被选中 即使在用户刷新页面或关闭浏览器并稍后返回之后
  • Firebase 函数 onWrite 未被调用

    我正在尝试使用 Firebase 函数实现一个触发器 该触发器会复制数据库中的一些数据 我想观看所有添加的内容votes user vote 结构为 我尝试的代码是 const functions require firebase func
  • 对于只触及我的工作表的 Google 表格脚本,收到“此应用程序未经验证”

    我正在编写一个 Google Sheets 脚本 我只想访问与 gs 文件关联的同一电子表格中的数据 似乎我应该有权在自己的电子表格中运行脚本 但是每当我运行一个函数时 我都会得到一个This app isn t verified信息 我该
  • 如何使用 crypto-js 解密 AES ECB

    我正在尝试将加密数据从 flash 客户端 发送到服务器端的 javascript 在 asp 中作为 jscript 运行 有几个 javascript Aes 库 但它们实际上没有文档记录 我正在尝试使用 crypto js 但无法让代
  • 在 Shopify 商店中嵌入 Vue 组件

    在产品页面中 我尝试显示自定义 Vue 组件 为简洁起见 该组件根据给定的产品 ID 显示 Firebase 数据库中的一些信息 我最初尝试将其制作为 Shopify 应用程序 以便我可以访问他们的 API 我实现了 OAuth 并且可以检
  • 如何隐藏/禁用 Highcharts.js 中的图例框?

    我想问是否可以使用 HighCharts js 库隐藏图表中的所有图例框 var chart object chart renderTo render to type graph type colors graph colors title
  • Javascript - 水波纹效果

    我需要 JS 上的脚本 它将以 水波纹 样式更改 images html 抱歉 6MB GIF 文件 http fcuunited ru temp listening2 gif http fcunited ru temp listening
  • 从 FileReader 设置背景图像样式

    我正在寻找一种解决方案 允许我从文件上传输入中获取文件并通过设置 document body style backgroundImage 来预览它 以下代码用于在 Image 元素中显示预览 function setImage id tar

随机推荐

  • unix下隐藏文件的正则表达式

    我正在寻找一个正则表达式来匹配以 开头的每个文件 在一个目录中 我正在使用 CMake 来自 CMake 文档 CMake 需要正则表达式 而不是 glob 并且想要忽略以点开头的每个文件 隐藏文件 但是 or 不起作用 奇怪的是 这有效
  • 使用 ScriptEngine (.NET 3.5) 在 C# 中执行 Selenium python 单元测试时遇到问题

    第一次海报 我正在转向关于堆栈溢出的第一个问题 因为我在尝试寻找答案时发现了很少的资源 我正在寻找从 C 应用程序执行 Selenium python 测试 我不想每次都编译 C Selenium 测试 我想利用 IronPython 脚本
  • 为什么 C++ 中 char 不被视为数字?

    我用 C 编写了一段代码 运行完美 我将其翻译为 C 那里给出了错误的输出 我有一个迭代 我将输入和迭代器变量都用作 char 以节省空间 但表现并不如预期 unsigned char repeat i cin gt gt repeat f
  • 处理日期/时间和时区的奇怪时间偏移

    我一直在尝试编写一些函数来根据谷歌电子表格上多个单元格的信息创建谷歌日历和谷歌日历事件 发布的第一期here日期部分已经得到解决 现在我在时间部分遇到问题 下面的代码 var ss SpreadsheetApp getActiveSprea
  • 有人可以向我解释一下这是什么类型吗? [复制]

    这个问题在这里已经有答案了 我发现了这种排序 有人可以向我解释一下它是什么类型吗 我认为这是选择排序对吗 嵌套循环如何工作 for i 0 i lt N i for j i 1 j lt N j if toSort i gt toSort
  • 数据总是在变化(SQL Server Management Studio)

    我正在使用 SQL Server Management studio 并不断收到相同的错误 摆脱它的唯一方法 通常 是重置 SQL Server 这非常烦人 有时在我的远程计算机上是不可能的 当我向表中添加一行 然后转到 编辑前 200 行
  • 在 PuTTY 中启动 SSH 连接,运行命令,并使会话保持活动状态

    我想每次通过 PuTTY SSH 到服务器时运行一些 shell 命令 我正在连接到由其他人管理的生产 Web 服务器 并且我不想在那里存储我自己的脚本 我看到了这个选项连接 gt SSH gt 远程命令 但是如果我将初始化命令放在那里 启
  • TypeScript:将键值类型反向映射到值键

    给定一个类型的对象 type Key2Value foo bar voo doo 假设该类型的值始终是字符串类型 如何构造实用程序类型ReverseMap
  • gprof 的替代品 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心以获得指导 Locked 这个问题及其
  • Spring JMS 和 Oracle AQ

    有人让 Spring JMS 与 Oracle AQ 队列一起使用吗 我正在尝试根据这篇文章连接到 AQhttp blog nominet org uk tech 2007 10 04 spring jms with oracle aq 但
  • 使用 Angular JS 标签(例如 ng-view)从网络获取文本

    我正在尝试从网站获取所有可见文本 我使用 python scrapy 来完成这项工作 然而 我观察到 scrapy 仅适用于 HTML 标签 如 div body head 等 而不适用于 Ang view 等角度 js 标签 如果 ng
  • MongoDB 使用 Node.js 获取集合中的文档数量(计数)

    我目前正在编写一个函数 该函数应该返回集合中的文档数量 问题是当我返回值时它显示未定义 这是我的代码 var MongoClient require mongodb MongoClient open the connection the D
  • 您如何处理源代码管理中的配置文件?

    假设您有一个典型的 Web 应用程序和一个文件配置 无论如何 每个从事该项目的开发人员都会有一个适用于他们的开发盒的版本 其中会有开发版 产品版和阶段版 您如何在源代码控制中处理这个问题 根本不签入该文件 用不同的名称检查它还是干脆做一些奇
  • 将整数除以 2 时哪个选项更好?

    以下哪种技术是将整数除以 2 的最佳选择 为什么 技巧一 x x gt gt 1 技巧2 x x 2 Here x是一个整数 使用最能描述您要执行的操作的操作 如果将数字视为位序列 请使用位移位 如果将其视为数值 请使用除法 请注意 它们并
  • 我可以将多个 MySQL 行连接到一个字段中吗?

    Using MySQL 我可以做类似的事情 SELECT hobbies FROM peoples hobbies WHERE person id 5 我的输出 shopping fishing coding 但我只想要 1 行 1 列 预
  • Hadoop 和图像 3D 渲染

    我必须制作一个项目 3D 图像的分布式渲染 我可以使用标准算法 目的是学习hadoop而不是图像处理 那么有人可以建议我应该使用哪种语言 c 或 java 以及 3d 渲染器的一些标准实现吗 任何其他帮助都会非常有用 Hadoop 使用映射
  • 使用 WebpackExternals 进行酶单元测试

    我目前正在测试一个依赖于带有 webpack 外部脚本的组件 DBPanel js import React PureComponent from react import from jquery webpack 外部文件如下所示 webp
  • 如何检查 NSDictionary 或 NSMutableDictionary 是否包含键?

    我需要检查字典是否有密钥 如何 objectForKey如果键不存在则返回 nil
  • 在 R 中提取文件名的一部分

    我正在尝试编写一些代码来打开文件夹中的所有数据文件 应用一个函数 或一组函数 来提取我感兴趣的数据 到目前为止 一切都很好 问题是我想使用文件名的一个元素重新命名我从每个文件中提取的列之一 但我很难弄清楚如何提取它 我有一堆名为 YYYY
  • 如何在 RxJS observable 中添加额外的字段并等待它完成?

    我有一个返回的可观察值items 我只需要一个特定的项目 并且我想从也可观察到的 http 请求向其添加一些额外的字段 下面的代码是我试图实现这一目标的方法 但它不起作用 我需要完成所有可观察量才能获取完整的项目数据ngOnInit 我缺少