RXJS 处理两个不同的事件,其中第一个事件必须取消第二个事件

2024-03-23

rxjs 对我来说非常具有挑战性,我发现自己一直在尝试解决这个问题。我在堆栈上找到的最接近的解决方案是使用合并运算符。这里是link https://stackoverflow.com/questions/45495188/rxjs-fromevent-to-handle-multiple-events

我正在 Angular 2 工作。

我有一个 html 输入搜索字段

<input (keydown.enter)="setFocus()" id="search-box" name="input-box" class="search-box" type="text" placeholder="Client search" (focus)="clearWarnings()" />

用户在字段框中键入内容,将在预设的延迟后触发相应的功能。用户也可以按回车键(和搜索图标)来触发搜索。我的目标是每当用户按下回车键时,去抖不应触发搜索,因为它已经在运行。

这是到目前为止使用合并函数的代码,尽管它似乎没有按照我想要的方式工作。

ngAfterViewInit() {
        this.currentMember = this.appHelpersService.getLocalStorageSearchedRim();
        if (this.currentMember) {
            this.searchService.changeSearchTerm(this.currentMember);
        }

        var waitTime = AppConstants.SEARCH_TEXT_WAITTIME;
        const searchSource = document.getElementById("search-box");
        const keydownStream = fromEvent(this.elementRef.nativeElement, 'keyup');
        const inputStream = fromEvent(searchSource, "input");
        const allStreams = merge(keydownStream, inputStream);
        allStreams
            .pipe(
                map((event: KeyboardEvent | MouseEvent) => (<HTMLInputElement>event.target).value.trim()),
                filter((searchTerm: string) => {
                    waitTime = Number(searchTerm) ? AppConstants.SEARCH_NUMERIC_WAITTIME : AppConstants.SEARCH_TEXT_WAITTIME;
                    return searchTerm.length >= 2;
                }),
                debounce(() => timer(waitTime)),
                distinctUntilChanged()
            )
            .subscribe((searchTerm: string) => {
                this.showProgressbar = true;
                this.listSearchResults(searchTerm);
            });

    }

以及回车键事件:

 setFocus(): void {
        const searchBox: HTMLElement = document.getElementById("search-box");
        const searchTerm = (<HTMLInputElement>searchBox).value;
        if (searchTerm && searchTerm.length > 0) {
            this.listSearchResults(searchTerm);
        }
        searchBox.focus();
    }

在解决方案中,我提到合并在一起的所有事件都会触发该函数,但不一定会取消正在等待的其他事件(反跳)。

感谢您抽出时间


我认为您的代码片段中有一些错误

const keydownStream = fromEvent(this.elementRef.nativeElement, 'keyup');

应该

const keyupStream = fromEvent(this.elementRef.nativeElement, 'keyUp');

你真的不需要另一个fromEvent自从你的keyupStream已经具有来自的值input

您的 Enter 函数调用和搜索“typeahead”函数调用必须包装在可观察对象中才能取消它们。

鉴于他们是你可以做类似的事情

const search$ = fromEvent(this.search.nativeElement, 'keyup').pipe(share());
const searchKeyEnter$ = search$.pipe(filter((e: KeyboardEvent) => e.keyCode === 13 || e.which === 13))
const searchText$ = search$.pipe(filter((e: KeyboardEvent) => e.keyCode !== 13 && e.which !== 13), debounceTime(500))

const mergeKeyDown = merge(searchText$.pipe(mapTo('search')), searchKeyEnter$.pipe(mapTo('enter')))
  .pipe(
  withLatestFrom(search$),
  filter(([origin, data]) => data.target.value.length > 2),
  distinctUntilChanged(),
  switchMap(([origin, data]) => {
    if (origin === 'search') {
      console.log('search started')
      return of('').pipe(delay(3000), tap(() => console.log('search call has finished')))
    } else {
      return of('').pipe(tap(() => console.log(' i got called from enter')));
    }
  })
  ).subscribe(() => { })

这里发生的事情是我们共享用户输入内容的事件

fromEvent(this.search.nativeElement, 'keyup').pipe(share());

这样我们就可以分发它来创建和组合特定类型的新可观察量

仅使用 Enter 键的示例:

search$.pipe(filter((e: KeyboardEvent) => e.keyCode === 13 || e.which === 13))

We use mapTo http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-mapTo这样我们就可以区分哪个事件被触发了。

当任何这些事件被触发时,我们希望再次重用刚刚从输入更新的值与最新来自 http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-withLatestFrom.

现在为了取消任何正在进行的异步任务切换映射 http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-switchMap可以使用运算符。

使用 Observables 时的一件大事是创建它们,以便您可以reuse and 创作它们.

我创建了一个 stackblitz,你可以 fork 并亲自尝试一下,注意控制台。

https://stackblitz.com/edit/merging-events?file=src/app/app.component.ts https://stackblitz.com/edit/merging-events?file=src/app/app.component.ts

希望这可以帮助!

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

RXJS 处理两个不同的事件,其中第一个事件必须取消第二个事件 的相关文章

  • 使用 Adob​​e PhoneGap + Angular2 时不显示图像(图片和 src)

    我使用 cli 创建了一个全新的项目 我尝试添加一些图像标签 每个标签都有不同类型的来源 本地图片 网络图片 https来源图片 在浏览器上 这可以很好地呈现所有内容 但是当使用 Adob e PhoneGap 通过 PhoneGap 桌面
  • 角度材料:尽管有正确的方法,但垫子错误并未显示

    我有一个要验证的确认密码表单控件 当密码与确认密码输入中的值不同时 我想显示我的 mat error 元素 为此我有一个名为equalPasswords 如果功能相同 则我们收到 true 如果不同 我们收到 false
  • 如何在 Angular2 中脏检查可迭代组件属性?

    看一下这个简单的 Angular2 组件 Component selector status area directives template require status area tpl jade export class Status
  • 什么是 Tree Shaking?为什么需要它?

    我已经开始学习 Angular 2 并且遇到了 tree shake 这个术语 但我无法从初学者的角度找到任何好的解释 我在这里有两个问题 什么是 Tree Shaking 为什么需要它 我该如何使用它 我看到你在这里有三个问题 1 什么是
  • 使用 MSAL 与 Angular 进行重定向_uri_mismatch Azure AD B2C

    使用时loginRedirect or acquireTokenRedirect 我收到以下错误 redirect uri mismatch AADB2C90006 3a 请求中提供的重定向 URI http 3a 2f 2flocalho
  • Angular2:如何在实现 routerCanDeactivate 时防止/取消历史操作?

    routerCanDeactivate 成功阻止导航离开组件 routerCanDeactivate nextInstruction ComponentInstruction prevInstruction ComponentInstruc
  • Angular 2 - 检查图像 URL 是否有效或损坏

    我正在从 API 获取大量图像 URL 并将它们显示在 Angular 2 Web 应用程序中 有些 URL 已损坏 我想用本地存储在我的网络服务器上的默认图片替换它们 有人建议如何测试 url 并在状态代码 404 的情况下替换损坏的图像
  • 如何根据 Angular 中的全局 CSS 类名调整组件的 CSS?

    我们正在使用一个类html 判断用户是否在的元素dark or light应用程序的模式 这个类是使用添加的Renderer2在检测用户所选设置的服务中 到目前为止效果很好 现在 我们必须调整所有组件 以便在黑暗模式下也能看起来很好 但问题
  • 为什么 ion-fab-button 没有固定在 ionic 4 popover 内?

    我正在开发一个 ionic 4 应用程序 并且创建了一个弹出窗口 在这个弹出窗口中我想使用ion fub button它必须固定在弹出窗口的右上角位置 我写的 HTML 代码是这样的
  • 更改内置颜色

    我只是想问如何更改 Angular 2 材质中的这些内置颜色 它在 ng2 material 文档中指定 color primary accent warn 如何更改这些调色板中的颜色 或者甚至如何改变文本的蓝色 我已经尝试过这个但行不通
  • Mat 分页器更改工具提示位置

    我正在尝试定位工具提示mat paginator更靠近分页按钮 目前 工具提示距离太远 如下所示 我尝试更新 cdk overlay pane and mat tooltip panel课程但对我不起作用 任何积分都受到高度赞赏 需要深入组
  • Angular 6. 是否可以按条件注入服务?

    在我的角度应用程序 带有角度材料 中 我有一个过滤器面板 除了选择之外 我还希望能够自动完成 用户输入值并将其发送到后端 通过 regexp 查询我们在 MongoDB 集合中找到匹配项 但要做到这一点 我需要手动将服务注入过滤器组件 我没
  • 注解和装饰器有什么区别?

    我很困惑何时使用术语注释以及何时使用装饰器 Component selector tabs template export class Tabs 装饰器对应于在类上调用的函数 而注释是使用 Reflect Metadata 库在类上设置的
  • 无法匹配任何路线。 URL 段:'':尝试使用子路由和 Ng2 时

    I have 以下笨蛋 https plnkr co edit PHaGNtfa0fPBgET4NEpZ p preview 这是行不通的 为了让它发挥作用 我可以评论 RouterModule forRoot path component
  • 在 ionic 中从 Base64 打开 pdf

    因此 我将 Jasper 报告转换为 pdf 然后在 REST 控制器中转换为 base64 我该如何将其传输到我的 ionic 3 应用程序 我研究了 Ionic Native Document Viewer 但为了做到这一点 我需要将文
  • Angular2 - 在 SystemJS 中导入第 3 方 javascript

    由于某种原因 fileSaver 没有被映射 angular2 jwt 工作正常 I did npm install file saver save获取文件保护程序 然后按如下方式引用它 我有一个 gulp 任务将 js 文件移动到 lib
  • 指令中的 Angular2 样式

    在属性指令 即添加外观 行为的指令 的给定示例中 我们在宿主元素上对样式进行了相当简单的设置 import Directive ElementRef from angular2 core Directive selector myHighl
  • Ng Bootstrap 日期范围选择器 [markDisabled] 不适用于输入

    我正在尝试禁用某些日期ng 引导范围选择器 https ng bootstrap github io components datepicker overview 目前 我在弹出窗口中有一个范围选择器 并且我正在使用 markDisable
  • 让管道自我刷新角度

    我有来自后端的静态时间戳 我想每 1 秒刷新一次管道以获取现在的日期 这是我的烟斗 import Pipe PipeTransform from angular core import moment from moment Pipe nam
  • 在 Angular 4 中处理来自 Api 的过期令牌

    我需要帮助来处理我的角度应用程序中的过期令牌 我的 api 已过期 但我的问题是当我忘记注销我的角度应用程序时 一段时间后 我仍然可以访问主页但没有数据 我能做点什么吗 有没有可以处理这个问题的库 或者有什么我可以安装的吗 更好 如果我什么

随机推荐

  • vim 中嵌入 awk 语法高亮

    我有一个语法文件 用于突出显示 bash 脚本中嵌入的 awk syn include AWKScript syntax awk vim syn region AWKScriptCode matchgroup AWKCommand star
  • PHPMailer 不发送 CC 或 BCC

    我已经测试以下代码几个小时了 该电子邮件将发送到通过以下方式添加的地址 mail gt AddAddress 在收到的电子邮件中注明了抄送 但抄送人没有收到电子邮件 我到处找过 但找不到解决办法来解释为什么会发生这种情况 我已经运行了测试
  • 获取 iPhone 上已安装应用程序的列表

    有没有办法 某些 API 来获取 iPhone 设备上已安装应用程序的列表 在搜索类似问题时 我发现了一些与url registration 但我认为必须有一些 API 来执行此操作 因为我不想对应用程序执行任何操作 我只想要列表 不 应用
  • 子域名指向同一IIS中的不同网站

    我有一个 IIS 服务器 运行一个默认网站 一个在 LandingPage 路径中运行的 React 应用程序以及一个由 api 中的 React 应用程序使用的 API 所以基本上我有 localhost 80 gt 默认 MVC 网站
  • C++ 类使用未定义类型

    我有一个我制作的类 我在类上方的线程中使用它 即使我在顶部做了一个类的原型 它仍然会抛出这些错误 错误 C2027 使用未定义类型 foo class foo DWORD WINAPI demo LPVOID param foo a cla
  • 如何在 React Native 中获取“打开前的键盘高度”?

    环境 React Native 0 60 4 Problem 我正在开发聊天应用程序 聊天有表情符号选择器 表情符号选择器必须与键盘具有相同的高度 我需要在键盘打开之前获取键盘的高度 我尝试使用键盘侦听器 但它们在打开后给出高度 我的最终目
  • 通过 Javascript 修改第 n 个子级

    是否可以使用纯js动态修改css nth child属性 tile nth child 10n 1 clear both 例如 像这样使用 js 添加 正如Pariket Thakur所说 你可以使用document querySelect
  • Spring Data (Spring Boot) 和 Joda Time 字段映射的问题

    我有一些带有 Joda DateTime 字段的实体 当尝试启动应用程序时 我收到以下错误 org springframework beans factory BeanCreationException Error creating bea
  • Hibernate Criteria 按子记录计数排序

    我有两个类 新闻和评论 它们之间具有一对多关联 我正在使用 Hibernate Criteria 从数据库中获取新闻 我希望我的新闻按照评论数排序 session createCriteria News class n criteria c
  • sql select语句给出列错误

    当我使用 SELECT order id from order where order id U687678601 我收到错误 错误 1054 未知列 where 子句中的 U687678601 但是当我输入时 SELECT order i
  • 是否有一个包含所有 Bootstrap 元素的巨大“资产页面”,我可以重新设置样式? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 http twitter github com bootstrap base css html htt
  • 在android的子目录中创建文件

    是否可以使用android中的openFileOutput方法在 data data packagename files 目录下创建的子目录中创建文件 即 data data packagename files 目录中有一个名为 text
  • Kohana——命令行

    我正在尝试在我的 Web 应用程序中 假分叉 一个进程 通过 SMTP 发送电子邮件 并且该应用程序是基于 Kohana 构建的 command test email exec php index php command gt dev nu
  • django-orm 不区分大小写的顺序

    我知道 我可以从 DJango ORM 运行不区分大小写的搜索 喜欢 User objects filter first name contains jake User objects filter first name contains
  • Android Compose 设置视图高度(以像素为单位而不是 dp)

    我想以像素而不是 dp 为单位设置视图高度 Box modifier Modifier height 100 dp 在此示例中 框的高度设置为 100 dp 并且修改器函数仅接受 dp 如何设置 Box 的高度 以像素为单位 Kilian
  • 在 Swift 中链接多个异步函数

    我正在尝试编写一系列函数 在要求用户确认某些内容之前验证用户的信息 想象一个购物应用程序 我首先必须检查用户是否添加了卡 然后我必须检查他们是否有足够的余额 然后我可以要求他们确认付款 我可以编写异步方法来检查卡 例如 func check
  • 使用 Javascript 生成高质量 PDF (jspdf+html2canvas)

    我一直在尝试通过单击页面上的按钮从 HTML 页面转换并生成 PDF 该按钮会使用两个流行的插件自动生成并强制下载页面的 PDF JSPDF HTML2Canvas 到目前为止 一切正常 但生成的 PDF 总是模糊且质量不高 导入 js 文
  • 这些 switch 语句有哪些替代方案?

    刚刚制作了这个极其简单的 GPA 计算器 想知道如何使用循环来避免大量的 switch 语句 我对 Java 很陌生 只是寻求一些建议 非常感谢任何其他改进程序的方法 预先感谢各位 package helloPackage import j
  • 出于好奇,学习Android开发

    最近我一直在考虑开发一些基本的android应用程序 这只是出于个人兴趣 请指导我从哪里开始 我需要什么工具以及指向某些 pdf 等的任何指示 我的背景 1 C语言嵌入式软件开发人员 2 有一些从事 Flex 工作的机会 因此熟悉eclip
  • RXJS 处理两个不同的事件,其中第一个事件必须取消第二个事件

    rxjs 对我来说非常具有挑战性 我发现自己一直在尝试解决这个问题 我在堆栈上找到的最接近的解决方案是使用合并运算符 这里是link https stackoverflow com questions 45495188 rxjs frome