[英]Rxjs, fromEvent handle multiple events
I am trying to combine multiple events blur
and keyup (enter key only)
using fromEvent
.我正在尝试使用
fromEvent
组合多个事件blur
和keyup (enter key only)
。 I have implemented blur event, how I can combine keyup.enter as well.我已经实现了 blur 事件,我也可以结合 keyup.enter 。
I have tried with the filter
operator but with the filter, enter is working onblur is not -我已经尝试过使用
filter
运算符,但是使用过滤器,输入正在工作 onblur 不是 -
Component.ts组件.ts
this.propertyDescription.forEach((input: ElementRef) => {
const events = ['blur', 'keyup'];
from(events)
.pipe(
takeUntil(this.unsubscribe$),
mergeMap((event) =>
fromEvent(input.nativeElement, event)
),
filter((e: KeyboardEvent) => e.key === 'Enter'),
map((evt: any) => evt.target.value),
distinctUntilChanged(
(pre: any, curr: any) =>
JSON.stringify(pre) === JSON.stringify(curr)
)
)
.subscribe((caption: string) => {
console.log(caption);
});
});
Subscription inside a forEach
is an inelegant design. forEach
中的订阅是一种不雅的设计。 It'd lead to multiple (potentially unhandled) subscriptions.它会导致多个(可能未处理的)订阅。 You could use
merge
with Array#map
.您可以将
merge
与Array#map
。
Also instead of using from
you could use merge
with multiple fromEvent
s.另外
from
您可以使用与多个fromEvent
merge
,而不是使用from
。
Try the following尝试以下
const events = ['blur', 'keyup'];
merge(
this.propertyDescription.map((input: ElementRef) =>
merge(
events.map((event: string) =>
fromEvent(input.nativeElement, event).pipe(
map((evt: any) => evt.target.value),
distinctUntilChanged((pre: any, curr: any) =>
JSON.stringify(pre) === JSON.stringify(curr)
)
)
)
)
)
).pipe(
takeUntil(this.unsubscribe$)
).subscribe((caption: string) => {
console.log(caption);
});
What you are doing now is sending "blur" and "keyup" to your main observable.您现在正在做的是将“blur”和“keyup”发送到您的主要可观察对象。
What you need to do is declare what the "keyup" event does, what the "blur" event does and the apply your logic.您需要做的是声明“keyup”事件的作用,“blur”事件的作用以及应用您的逻辑。
Something more like:更像是:
this.propertyDescription.forEach((input: ElementRef) => {
const blurEvent$ = fromEvent(input.nativeElement, 'blur').pipe(/* your logic for "blur" event */);
const keyupEvent$ = fromEvent(input.nativeElement, 'keyup').pipe(/* your logic for "keyup" event */);
merge(blurEvent$, keyupEvent$).pipe(
takeUntil(this.unsubscribe$),
/* rest of your logic */
)
.subscribe();
}
Edit: merge does not take an array.编辑:合并不接受数组。 see on stackblitz
在stackblitz上看到
better way to do it in angular would be to send events from template更好的方法是从模板发送事件
<input #inp (keyup.enter)="valueUpdates$.next(inp.value)" (blur)="valueUpdates$.next(inp.value)">
//ts
valueUpdates$ = new Subject<string>();
this.valueUpdates$
.pipe(distinctUntilChanged())
.subscribe((caption: string) => console.log(caption));
If you just want to listen to changes that have been made after leaving the input element ( blur
) or after the user clicked Enter, you could just use the change
event instead.如果您只想听听离开输入元素 (
blur
) 或用户单击 Enter 后所做的更改,则可以改用change
事件。
However, if there is some reason you explicitly want to use blur
and keyup
with Enter, you have to fix your filter
operator.但是,如果您
keyup
某种原因明确希望在 Enter 中使用blur
和keyup
,则必须修复filter
运算符。 Right now, you're filtering out all Events that have no key
property with the value 'Enter'.现在,您正在过滤掉所有没有值为“Enter”的
key
属性的事件。 The FocusEvent
blur
doesn't have that property, so the filter function returns false
. FocusEvent
blur
没有该属性,因此 filter 函数返回false
。
A working filter should look something like this:工作过滤器应如下所示:
filter((e: KeyboardEvent | FocusEvent) => e instanceof FocusEvent || e.key === 'Enter'),
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.