angular - 如果不使用默认值,则 Angular @HostListener 延迟单击直到给出输入
问题描述
我正在努力完成这项工作。我想要实现的是以下。
我有一个带有该指令检查的属性输入的指令,但如果没有给出输入,它会使用指令本身定义的一些默认值。但是点击处理本身总是发生在输入值到达之前。所以它总是检查错误的输入(默认输入)。我也尝试过使用一些 rxjs,但是有些问题。该指令如下所示。
如果我记录exceptions
@Oninit
订阅,它甚至不会记录任何内容。我如何调整我的指令以使其在需要时工作?
一些代码可以更好地理解
private onChangeSub$ = new Subject<AutoSaveExceptions>();
private readonly clicks$ = new Subject<HTMLElement>();
private someStream$: Subscription;
private subscription$: Subscription;
ngOnChanges(changes: SimpleChanges) {
if (changes && changes['exceptions'] && changes['exceptions'].firstChange === true) {
this.onChangeSub$.next(changes['exceptions'].currentValue);
console.log(changes['exceptions'].currentValue);
}
}
ngOnInit() {
console.log('oninit');
this.subscription$ = this.onChangeSub$.pipe(
defaultIfEmpty(this.inlineDefaultExceptions)
).subscribe((exceptions) => {
this.exceptionAttributes = exceptions;
});
this.someStream$ = this.clicks$.pipe(
delay(300),
).subscribe((target) => this.handleClicks(target));
}
@HostListener('document:click', ['$event.target'])
onClick(target: HTMLElement) {
this.clicks$.next(target);
}
@Edit: 没有指令的基本想法复制
解决方案
首先,您必须避免@HostListener('document:click', ['$event.target'])
一般使用。这可能成为主要性能问题的根源。原因是对于您的指令/组件的每个实例,您注册的文档点击次数与您拥有的指令/组件实例一样多,所有这些都会严重触发更改检测。小心那个。
如果你想听全局点击,你应该做的是这样的:
const documentClick$: Observable<MouseEvent> = fromEvent(document, 'click').pipe(publish(), refCount());
export const DOCUMENT_CLICK = new InjectionToken('DOCUMENT_CLICK', {providedIn: 'root', factory: () => documentClick$});
然后将其注入到您的组件/指令中:
constructor(@Inject(DOCUMENT_CLICK) private readonly documentClick$: Observable) {}
然后你可以用它做任何类型的 rxjs 魔法,它会确保你在整个应用程序中最多只有一个文档点击监听器。更少的变更检测运行 - 更好的性能。
现在您可以过滤您的 click$ 流,直到您进行更改:
this.documentClick$.pipe(
withLatestFrom(this.onChangeSub$) // should not emit anything further until this stream emits, if it does, just add a filter
filter(([event, changes]) => ... ) // check that it's not default
).subscribe(() => ...) // handle there for example
编辑:elementRef
您的指令可以检查编辑状态并与我上面提到的一起
注入documentClick$
,然后当启用编辑时,指令可以侦听全局单击并以检查它是否在我们的元素之外进行处理,如果是则触发将导致自动保存的事件. 这是stackblitz 链接。
推荐阅读
- linux-kernel - 从内核调用 local_irq_disable() 也会禁用用户空间中的本地中断?
- javascript - 有什么方法可以在源代码中显示动态标签?
- android - 如何为约束布局组提供垂直边距?
- spring-security - 黄瓜测试,jhipster 和 oauth:找不到 ClientRegistrationRepository bean
- selenium-webdriver - 检查硒中是否存在元素
- vb.net - 无法读取文本文件 vb.net 中的多行
- google-apps-script - 如何在谷歌脚本/谷歌表中获取给定行的链接?
- css - 带页脚的 Vue Quasar 布局抽屉
- algorithm - 在硬币找零问题中减小数组的大小?
- azure - 如何将 Microsoft Identity Platform 与 Delphi VCL 程序一起使用?