作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我喜欢能够将 DOM 事件作为可观察流处理,调用过滤器、concatMap 等,如下例所示。
@Component({
template: `<button #btn>Submit<button`,
selector: 'app-test',
})
class TestComponent implements AfterViewInit, OnDestroy {
private destroy$ = new Subject<boolean>();
@ViewChild('btn') private btn: ElementRef<HtmlButtonElement>;
constructor(private testService: TestService) { }
ngAfterViewInit() {
fromEvent(btn.nativeElement, 'click').pipe(
exhaustMap(() = > {
return this.testService.save();
}),
takeUntil(this.destroy$),
).subscribe();
}
ngOnDestroy() {
this.destroy$.next(true);
this.destroy$.complete();
}
}
但有时我想从中监听事件的元素在 *ngIf 后面并且在 ngAfterViewInit 运行时不存在。仍然以 react 方式监听事件的最佳方式是什么?
我尝试的一种方法是在检查 ElementRef
是否存在的 if 语句后面的 ngOnViewChecked
中设置与上面相同的订阅,并带有一个标志以避免多个订阅。但我发现那很乱。
这样做是好的做法吗?
@Component({
template: `<button (click)="clickEvent.emit()">Submit<button`,
selector: 'app-test',
})
class TestComponent implements OnInit, OnDestroy {
private destroy$ = new Subject<boolean>();
clickEvent = new EventEmitter<void>();
constructor(private testService: TestService) { }
ngOnInit() {
this.clickEvent.pipe(
exhaustMap(() = > {
return this.testService.save();
}),
takeUntil(this.destroy$),
).subscribe();
}
ngOnDestroy() {
this.destroy$.next(true);
this.destroy$.complete();
}
}
我应该用 Subject
替换 EventEmitter
吗?有没有比这些更好的方法?
编辑:为了清楚起见,我的问题与从由于 *ngIf 而可能不存在的元素订阅事件有关
最佳答案
使用 @ViewChildren
和 QueryList
来监听 DOM 变化。
import { Component, AfterViewInit, OnDestroy, ElementRef, ViewChildren, QueryList } from '@angular/core';
import { Subject, fromEvent, of } from 'rxjs';
import { exhaustMap, takeUntil, switchMap, map, filter } from 'rxjs/operators';
@Component({
selector: 'app-test',
template: `<button #btn>Submit<button`
})
export class TestComponent implements AfterViewInit, OnDestroy {
private destroy$ = new Subject<boolean>();
// Any time a child element is added, removed, or moved,
// the query list will be updated, and the changes observable
// of the query list will emit a new value.
@ViewChildren('btn') private btn: QueryList<ElementRef>;
constructor(private testService: TestService) { }
ngAfterViewInit() {
this.btn.changes.pipe(
// only emit if there is an element and map to the desired stream
filter((list: QueryList<ElementRef>) => list.length > 0),
switchMap((list: QueryList<ElementRef>) => fromEvent(list.first.nativeElement, 'click')),
// add your other operators
exhaustMap(() => this.testService.save()),
takeUntil(this.destroy$),
).subscribe(console.log);
// Trigger a change event to emit the current state
this.btn.notifyOnChanges()
}
ngOnDestroy() {
this.destroy$.next(true);
this.destroy$.complete();
}
}
关于angular - 订阅 *ngIf 背后的 DOM 事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61810604/
我正在寻找匹配 /(?=\W)(gimme)(?=\W)/gi 或类似的东西。 \W 应该是零宽度字符来包围我的实际匹配项。 也许有一些背景。我想用添加的文字填充替换某些单词(总是 \w+),但前提是
如何在不使用 Intent 连接到 VPN 服务的情况下以编程方式检测流量是否正在通过 VPN。有系统调用吗? 最佳答案 这个有效: private boolean checkVPN() {
我是一名优秀的程序员,十分优秀!