web-dev-qa-db-ja.com

Angular2の<button>クリックイベントから観察可能

Angular 2?

コンポーネントコードでネイティブ要素をDOMから取得するのがベストプラクティスと見なされるか(どうすればよいのか)、または他の知らないショートカットがあるかどうかはわかりません。

30
GBa

「Observable_1.Observable.fromEventは関数ではありません」エラーを取得するAngular2 RxJSで説明されているように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)">
27

考えすぎないでください。

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

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

私のコンパイラは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>
10
Jon

@ViewChildを使用しようとして、初期化時にボタンがページに表示されない場合(* ngIfが原因)、割り当てはnullになります。

セッターを@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で大丈夫であり、どちらも実装の詳細です。まあそれはあなた次第です-)

2
Simon_Weaver

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
joedev