如何在Angular 6中使用rxjs fromEvent定位HTML元素

12

问题

我使用了 ngrx 的 fromEvent 操作符从 2 个输入文本框创建了 Observable,我使用的是文档作为目标,这很好,但现在我想只针对一个输入文本框进行操作。我不确定该使用什么来替代 document 来指定只有一个输入文本框。

我已经尝试过的方式来获取目标

  • 使用 document.getElementByID('someID')
  • 使用 ElementRef
  • 使用 document.querySelector('someID')

代码

StackBlits 实时编辑器

import { Component } from '@angular/core';
import { fromEvent } from 'rxjs';

@Component({
  selector: 'my-app',
  template: `<input type="text">
             <input type="text">`
})
export class AppComponent {
  ngOnInit() {
    fromEvent(document, 'keyup')
      .subscribe(res => console.log(res.target.value));
  }
}

提前感谢你的帮助。

2个回答

18
你可以给想要观察的字段设置一个模板变量。
然后,你可以使用@ViewChild来访问该。接着,使用其上的nativeElement属性。
现在,只有在视图初始化后才能访问nativeElement属性。因此,你可以使用AfterViewInit组件生命周期钩子来访问它。
import { Component, ViewChild, ElementRef } from '@angular/core';
import { fromEvent } from 'rxjs';

@Component({
  selector: 'my-app',
  template: `<input #toTarget type="text">
             <input type="text">`
})
export class AppComponent {

  @ViewChild('toTarget') toTarget: ElementRef;

  ngAfterViewInit() {
    fromEvent(this.toTarget.nativeElement, 'keyup')
      .subscribe(res => console.log(res.target.value));
  }
}

这是一个更新的 StackBlitz,供您参考。

1
应该在 ngAfterViewInit 中访问 @ViewChild 属性,因为它们是在视图初始化后设置的,前提是该元素没有 ngIf/ngFor 指令。 - Safal Pillai
@SafalPillai,有道理。非常感谢您指出来。我已经更新了我的答案。 :) - SiddAjmera

1
如果您正在使用Angular 8+阅读此内容,正确引用@ViewChild元素并能在ngOnInit中使用它们的方法是:
import { Component, ViewChild, ElementRef, OnInit, OnDestroy } from '@angular/core';
import { fromEvent } from 'rxjs';

@Component({
  selector: 'my-app',
  template: `
    <input #yourTarget type="text">
    <input type="text">
  `
})
export class AppComponent implements OnInit, OnDestroy {
  @ViewChild('yourTarget', {static: true}) yourTarget: ElementRef;

  subscriptions = new Subscription();

  ngOnInit(): void {
    subscriptions.add(
      fromEvent(this.yourTarget.nativeElement, 'keyup')
        .subscribe(res => console.log(res.target.value))
    )
  }

  ngOnDestroy(): void {
    subscriptions.unsubscribe();
  }
}

注意在@ViewChild声明中的{static: true}: 它会让Angular知道引用的元素已经在"OnInit"生命周期中存在。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接