【问题标题】:How to subscribe to an element's (that not exist yet) event如何订阅元素的(尚不存在)事件
【发布时间】:2019-12-08 08:53:38
【问题描述】:

我想创建一个可观察到的订阅可能尚不存在的元素上的事件。如果没有找到该元素,它会重试直到找到该元素。

问题是 TypeScript 不喜欢它。

当我在 observable 上调用 .pipe(...) 时出现错误。错误出现在我输入pipe 的任何内容上,在本例中为retryWhen(...)。如果我不使用pipe,则不会出错。

这是我的代码:

import { Observable } from 'rxjs'
import { retryWhen, delay } from 'rxjs/operators'

export const scroll$ = new Observable((subscriber) => {
  const scrollbox = document.querySelector('.section-scrollbox')

  if (scrollbox) {
    scrollbox.addEventListener('scroll', handleEvent)

    return scrollbox.removeEventListener('scroll', handleEvent)
  } else {
    subscriber.error()
  }

  function handleEvent(this: HTMLDivElement) {
    subscriber.next(this)
  }
}).pipe(
  retryWhen((errors) => errors.pipe(delay(1000))),
)

我收到以下错误:

“MonoTypeOperatorFunction”类型的参数不可分配给“OperatorFunction”类型的参数。

参数'source'和'source'的类型不兼容。

类型“Observable”不可分配给类型“Observable”。

类型“未知”不可分配给类型“HTMLDivElement”.ts(2345)

在这种情况下如何将类型设置为Observable<HTMLDivElement>

顺便说一句,这不是 Angular 问题。我在 Chrome 扩展内容脚本中使用它。

【问题讨论】:

  • 可能不相关,但将 return 和 void 函数调用结合起来是个坏主意,可能会混淆 TS 编译器,因此我建议将它们分开。
  • 你想检查元素是否以 1 秒的间隔存在,如果存在则订阅它的“滚动”事件?
  • @benshabatnoam 既然你这么说,interval + switchMap 将是一个更好的解决方案......
  • 10x 你的问题,让它工作很有趣。检查我的答案。

标签: typescript google-chrome-extension rxjs


【解决方案1】:

这个 observable 可以完成这项工作:

const scroll$ = timer().pipe(
  switchMap(() => of(document.querySelector('.section-scrollbox'))),
  switchMap(bodyDiv => fromEvent(bodyDiv, 'scroll')),
  retryWhen(errors => errors.pipe(
    delay(1000)
  ))
);

说明:

  1. timer - 发出 1 个值然后完成。

    这只是为了初始化 observable 来寻找你的元素。

  2. switchMap(() => of(document.querySelector('.section-scrollbox')))

    如果存在则返回你的元素

  3. switchMap(bodyDiv => fromEvent(bodyDiv, 'scroll'))

    如果您的元素存在将从现在开始返回滚动事件(不再寻找该元素)

  4. retryWhen(errors => errors.pipe(delay(1000)))

    如果您的元素不存在将重试第 2 步以再次获取您的元素,之后 延迟 1 秒。

查看此DEMO

【讨论】:

    猜你喜欢
    • 2016-08-14
    • 2013-11-03
    • 2022-11-07
    • 1970-01-01
    • 2015-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多