我对RXJS还是个新手.我想要实现的是,当用户按下空格键(或任何其他)键并用鼠标拖动元素时,拖动HtmlElement.

因此,拖动的开始是由空格-DOWN_LeftClick或LeftClick_SPACE-DOWN触发的.两者都被接受,以方便使用. 通过松开空格键(KeyUp事件)或鼠标单击(MouseUp事件)来触发拖动的结束,以最先发生的那个为准.

实现的 idea 是有一个‘DragStart’可观察到的和一个‘Dragend’可观察到的,我可以订阅. 我有4个与事件对应的观察点,首先按特定的键(空格)和鼠标键(左键)过滤:

spaceDown$ = fromEvent<KeyboardEvent>(document, "keydown").pipe( filter(key => key.code === 'Space'))

spaceUp$ = fromEvent<KeyboardEvent>(document, "keyup").pipe( filter( key => key.code === 'Space'))

mouseDown$ = fromEvent<MouseEvent>(document, "mousedown").pipe( filter( mouse => mouse.button == 0))

mouseUp$ = fromEvent<MouseEvent>(document, "mouseup").pipe( filter( mouse => mouse.button == 0))

我正在努力解决的是如何在RXJS中实现所需的行为.我试过用‘comineLatest’,‘with LatestFrom’,‘merge’不同的流,但它们都没有我想要的效果.

你有什么办法解决这个问题吗?

推荐答案

我会将震源可观测值映射到布尔值,其中TRUE表示按下.然后创建键盘和鼠标的组合观察点.然后再把这两条流结合起来.如果这两个值都为真,则表示拖动开始事件,否则为拖动结束.

const spaceDown$ = fromEvent<KeyboardEvent>(document, 'keydown').pipe(
  filter((key) => key.code === 'Space'),
  map(() => true)
);

const spaceUp$ = fromEvent<KeyboardEvent>(document, 'keyup').pipe(
  filter((key) => key.code === 'Space'),
  map(() => false)
);

const mouseDown$ = fromEvent<MouseEvent>(document, 'mousedown').pipe(
  filter((mouse) => mouse.button == 0),
  map(() => true)
);

const mouseUp$ = fromEvent<MouseEvent>(document, 'mouseup').pipe(
  filter((mouse) => mouse.button == 0),
  map(() => false)
);

const key$ = merge(spaceDown$, spaceUp$).pipe(startWith(false));
const mouse$ = merge(mouseDown$, mouseUp$).pipe(startWith(false));

const combined$ = combineLatest([
  key$,
  mouse$,
]).pipe(
  map(([key, mouse]) => key && mouse),
  distinctUntilChanged(),
);

combined$.subscribe((res) => console.log('combined$', res));

// If different streams are required for dragstart and dragend:

const [dragStart$, dragEnd$] = partition(combined$, (val) => val);

dragStart$.subscribe(() => console.log('dragStart$'));
dragEnd$.subscribe(() => console.log('dragEnd$'));

Typescript相关问答推荐

如何根据数据类型动态注入组件?

rxjs forkJoin在错误后不会停止后续请求

在映射类型中用作索引时,TypeScrip泛型类型参数无法正常工作

对数组或REST参数中的多个函数的S参数进行类型判断

泛型类型联合将参数转换为Never

在嵌套属性中使用Required

在分配给类型的只读变量中维护const的类型

类型脚本满足将布尔类型转换为文字.这正常吗?

Angular文件上传到Spring Boot失败,多部分边界拒绝

如何将v-for中的迭代器编写为v-if中的字符串?

声明文件中的类型继承

下载量怎么会超过下载量?

为什么TS2339;TS2339;TS2339:类型A上不存在属性a?

声明遵循映射类型的接口

扩展对象的此内容(&Q;)

编剧- Select 下拉框

如何实现允许扩展泛型函数参数的类型

如何创建允许使用带有联合类型参数的Array.from()的TS函数?

如何在由函数参数推断的记录类型中具有多个对象字段类型

如何强制对象数组中的对象属性具有非空字符串值?