可从 Angular2 中的 <button> click 事件观察到
Observable from <button> click event in Angular2
使用 Angular 2 从按钮的 onclick 事件创建可观察对象的首选方法是什么?
我不确定从组件代码中的 DOM 获取本机元素是否被认为是最佳实践(我该怎么做?),或者是否有其他一些我不知道的快捷方式知道。
您可以像
中解释的那样使用 Observable.fromEvent
或者只是转发到像
这样的可观察对象
private obs = new Subject();
public obs$ = this.obs.asObservable();
@HostListener('click', ['$event'])
clickHandler(event){
this.obs.next(event);
}
或
<button (click)="obs.next($event)">
@Gunter 的示例对我来说不太适用,因为我的编译器无法识别 publ
.
这是一个对我有用的例子:
modal.component.ts
import { Output, Component } from '@angular/core';
import {Subject} from "rxjs/Subject";
export class MyModal{
private clickStream = new Subject<Event>();
@Output() observ = this.clickStream.asObservable();
buttonClick(event:Event){
this.clickStream.next(event);
}
}
里面 modal.component.html
:
<button type="button" class="btn btn-default" (click)="buttonClick($event)">click me</button>
别想太多了。
@ViewChild('button') button;
clicks$:Observable<any>;
ngOnInit() {
this.clicks$ = Observable.fromEvent(this.button.nativeElement, 'click');
}
对于那些使用 AngularMaterial 按钮和可管道化 RxJS 运算符的人,对@JoshuaDavid 的回答进行了一些轻微修改:
模板中用模板变量标记的一些按钮:
<button #btnTemplateName mat-icon-button></button>
组件代码:
import { Observable, fromEvent } from 'rxjs';
// Note importing from lettable/pipeable operators - 'operators' plural
import { tap } from 'rxjs/operators';
import { MatButton } from '@angular/material/button';
//Access the button through the template variable, typed to MatButton
@ViewChild('btnTemplateName') myBtn: MatButton;
myBtnClicks$: Observable<any>;
ngAfterViewInit() {
// Note the need to access the native element in MatButton through the extended property chain
this.myBtnClicks$ =
Observable.fromEvent(this.myBtn._elementRef.nativeElement, 'click');
// Can now subscribe (using lettable/pipeable operators)
this.myBtnClicks$.pipe(
tap(() => console.log("Button clicked")),
)
.subscribe(event => console.log("Event:" + JSON.stringify(event)));
}
如果您尝试使用 @ViewChild 并且您的按钮在初始时在页面上不可见(由于 *ngIf),则分配将为空。
您可以将 setter 与 @ViewChild 结合使用,并 运行 在按钮首次出现时进行初始化。
@ViewChild('btnAdd')
set btnAdd(btnAdd: Button) { ... }
这很快就会变得笨拙和不方便 - 特别是如果您从中创建一个可观察的流。
混合方式可能如下:
btnAskAnotherClicks$ = new Subject<Event>();
<button mat-flat-button (click)="btnAskAnotherClicks$.next($event)">Ask another question...</button>
这允许您使用点击流来创建链,但如果按钮最初因 *ngIf 而隐藏则没有问题。
不喜欢模板中的 next
?我也不特别。但我同意 async
,它们都是实现细节。好吧,由你决定 -)
使用 Angular 2 从按钮的 onclick 事件创建可观察对象的首选方法是什么?
我不确定从组件代码中的 DOM 获取本机元素是否被认为是最佳实践(我该怎么做?),或者是否有其他一些我不知道的快捷方式知道。
您可以像
Observable.fromEvent
或者只是转发到像
这样的可观察对象private obs = new Subject();
public obs$ = this.obs.asObservable();
@HostListener('click', ['$event'])
clickHandler(event){
this.obs.next(event);
}
或
<button (click)="obs.next($event)">
@Gunter 的示例对我来说不太适用,因为我的编译器无法识别 publ
.
这是一个对我有用的例子:
modal.component.ts
import { Output, Component } from '@angular/core';
import {Subject} from "rxjs/Subject";
export class MyModal{
private clickStream = new Subject<Event>();
@Output() observ = this.clickStream.asObservable();
buttonClick(event:Event){
this.clickStream.next(event);
}
}
里面 modal.component.html
:
<button type="button" class="btn btn-default" (click)="buttonClick($event)">click me</button>
别想太多了。
@ViewChild('button') button;
clicks$:Observable<any>;
ngOnInit() {
this.clicks$ = Observable.fromEvent(this.button.nativeElement, 'click');
}
对于那些使用 AngularMaterial 按钮和可管道化 RxJS 运算符的人,对@JoshuaDavid 的回答进行了一些轻微修改:
模板中用模板变量标记的一些按钮:
<button #btnTemplateName mat-icon-button></button>
组件代码:
import { Observable, fromEvent } from 'rxjs';
// Note importing from lettable/pipeable operators - 'operators' plural
import { tap } from 'rxjs/operators';
import { MatButton } from '@angular/material/button';
//Access the button through the template variable, typed to MatButton
@ViewChild('btnTemplateName') myBtn: MatButton;
myBtnClicks$: Observable<any>;
ngAfterViewInit() {
// Note the need to access the native element in MatButton through the extended property chain
this.myBtnClicks$ =
Observable.fromEvent(this.myBtn._elementRef.nativeElement, 'click');
// Can now subscribe (using lettable/pipeable operators)
this.myBtnClicks$.pipe(
tap(() => console.log("Button clicked")),
)
.subscribe(event => console.log("Event:" + JSON.stringify(event)));
}
如果您尝试使用 @ViewChild 并且您的按钮在初始时在页面上不可见(由于 *ngIf),则分配将为空。
您可以将 setter 与 @ViewChild 结合使用,并 运行 在按钮首次出现时进行初始化。
@ViewChild('btnAdd')
set btnAdd(btnAdd: Button) { ... }
这很快就会变得笨拙和不方便 - 特别是如果您从中创建一个可观察的流。
混合方式可能如下:
btnAskAnotherClicks$ = new Subject<Event>();
<button mat-flat-button (click)="btnAskAnotherClicks$.next($event)">Ask another question...</button>
这允许您使用点击流来创建链,但如果按钮最初因 *ngIf 而隐藏则没有问题。
不喜欢模板中的 next
?我也不特别。但我同意 async
,它们都是实现细节。好吧,由你决定 -)