可以从Angular2中的click事件中观察到

问题描述 投票:28回答:5

使用Angular 2从按钮的onclick事件创建observable的首选方法是什么?

我不确定在组件代码中从DOM中获取本机元素是否被认为是最佳实践(我该怎么做?),或者如果还有其他一些我不知道的快捷方式。

angular rxjs angular2-observables
5个回答
27
投票

您可以像Observable.fromEvent中所解释的那样使用Angular2 RxJS getting 'Observable_1.Observable.fromEvent is not a function' error

或者只是转发给像这样的观察者

private obs = new Subject();
public obs$ = this.obs.asObservable();

@HostListener('click', ['$event']) 
clickHandler(event){
  this.obs.next(event);
}

要么

<button (click)="obs.next($event)">

36
投票

不要过度思考它。

@ViewChild('button') button;
clicks$:Observable<any>;

ngOnInit() {
  this.clicks$ = Observable.fromEvent(this.button.nativeElement, 'click');
}

10
投票

@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>

2
投票

对于那些使用AngularMaterial按钮和可管理的RxJS运算符的人来说,@ JoshuaDavid的答案有一些轻微的修改:

模板中的某些按钮标有模板变量:

<button #btnTemplateName mat-icon-button></button>

组件代码:

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/fromEvent';

//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)));
}

2
投票

如果您尝试使用@ViewChild并且您的按钮在初始时在页面上不可见(由于* ngIf),则赋值将为null。

您可以将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没问题,而且它们都是实现细节。嗯,这取决于你决定 - )

© www.soinside.com 2019 - 2024. All rights reserved.