为什么Angular类型提前示例(去抖动)使用rxjs fromEvent而不使用Renderer2.listen?

时间:2019-05-24 14:33:40

标签: angular rxjs

《实用可观察物》的Angular手册提供了在type-ahead中使用去抖动的示例:

const typeahead = fromEvent(searchBox, 'input').pipe(
  map((e: KeyboardEvent) => e.target.value),
  filter(text => text.length > 2),
  debounceTime(10),
  distinctUntilChanged(),
  switchMap(() => ajax('/api/endpoint'))
);

同时,手册的另一部分建议使用Renderer2.listen()进行DOM交互。另外,此Medium post提出了一些非常有力的建议,建议不要直接操作DOM。

我已经阅读了与Q&A相关的“点击”事件,该事件可能适用于“输入”事件。

让我感到困扰的是,我在整个Angular手册中都在寻找一致的设计理念(其中包含很多内容)。这感觉不一致。

此外,两种方法也不完全相同。

对于Renderer2.listen(),将返回unlisten()函数以防止内存泄漏。 fromEvent并非如此。我怀疑fromEvent没有泄漏,但我不知道,更重要的是,如果泄漏,手册为什么会推荐这种方法?

最后,我接受这两种方法之间可能完全没有区别。那么,在这种情况下,手册肯定会偏向使用Renderer2

哪个让我问起前面的类型建议比listen()方法更好?


更新

我非常感谢您的回答和评论,他们共同为我澄清了一些事情。基本上,事件模型世界中的编码使开发人员感到非常复杂。 rxjs似乎是对那个世界的回应,这是一种使用事件的更简单/更简洁的方式。我也很欣赏实质上回答为“ RTFM”的答案,所以我也去做了。

如果我决定必须使用Renderer2.listen(),但是我也想利用Observables的简单编程模型,则必须将listen()调用转换为Observable。我相信看起来像这样:

new Observable(obs => renderer.listen(el.nativeElement, 'input', e => obs.next(e)))

最后,我想像fromEvent运算符会在幕后进行。

使用fromEvent代码的好处还在于,我不必在组件中注入Renderer2,只需要为目标DOM找到ElementRef宾语。关键是,我可以采用任何一种Observable方式,其中一种方式更易于描述和编码。

2 个答案:

答案 0 :(得分:1)

代码正上方的句子:

  

使用完整的JavaScript编写此代码可能会涉及很多。借助observable,您可以使用一系列简单的RxJS运算符:

这意味着它只是RxJS,不涉及Angular。只是为了解释RxJS的基础。

答案 1 :(得分:1)

fromEvent是可观察到的热门,因此可能会泄漏。为了获得最佳实践,它必须取消订阅为大多数Observable。

Renderer2.listen()似乎旨在在事件发生时采取行动,而使用fromEvent则可以对流本身进行更多控制。您可以使用debounceTimefilter等更改代码段中的行为。

因此,使用fromEvent您可以控制该流,而使用Renderer2.listen()您可以产生一些副作用等。