用Angular 2从按钮的onclick事件创建observable的首选方式是什么?
我不确定在组件代码中从DOM获取原始元素是否被认为是最佳实践(如何做到这一点?),或者是否有其他我不知道的捷径。
用Angular 2从按钮的onclick事件创建observable的首选方式是什么?
我不确定在组件代码中从DOM获取原始元素是否被认为是最佳实践(如何做到这一点?),或者是否有其他我不知道的捷径。
不要想太多。
@ViewChild('button') button;
clicks$:Observable<any>;
ngOnInit() {
this.clicks$ = Observable.fromEvent(this.button.nativeElement, 'click');
}
button
的 setter 和 flatmap/switchmap),但它很快会变得复杂。在这种情况下最好使用 Jon 的答案。 - Simon_WeaverObservable.fromEvent()
已被弃用。请改用 fromEvent()
,而不是 Observable.fromEvent()
。 - Cichy你可以像Angular2 RxJS getting 'Observable_1.Observable.fromEvent is not a function' error中所解释的那样使用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)">
由于我的编译器无法识别publ
,所以@Gunter的示例对我没有起作用。
这是一个对我有用的示例: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,而按钮在初始化时(由于*ngIf)不可见,则赋值将为空。
您可以与@ViewChild一起使用setter,在按钮首次出现时运行初始化。
@ViewChild('btnAdd')
set btnAdd(btnAdd: Button) { ... }
这种方法很快就会变得笨拙和不方便 - 特别是如果你从中创建了一个可观察的流。
一种混合方式可能如下:
btnAskAnotherClicks$ = new Subject<Event>();
<button mat-flat-button (click)="btnAskAnotherClicks$.next($event)">Ask another question...</button>
next
?我也不是特别喜欢。但是我可以接受 async
,它们都是实现细节。好吧,这取决于您的决定 -)new Subject<void>()
然后进行 btn.next()
而无需传递值。 如果事件没有有用的含义,这可能很有用。 - Simon_Weaver如果您正在使用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)));
}