angular2:使用服务广播事件

angular 2: using a service to broadcast an event

我试图让一个组件中的按钮单击以将焦点放在另一个组件上的元素上。 (坦率地说,我不明白为什么这必须如此复杂,但我还没有能够实现任何更简单且实际有效的方法。)

我正在使用一项服务。它不需要传递任何数据,除了 发生了点击。我不确定监听组件是如何响应事件的。

app.component:

跳到主要内容

import { Component } from '@angular/core';
import { SkipToContentService } from './services/skip-to-content.service';


export class AppComponent {
    constructor(
        private skipToContent: SkipToContentService
    ) {}
    }

    skipLink() {
        this.skipToContent.setClicked();
    }

}

登录组件:

<input type="text" name="username" />


import { Component, OnInit } from '@angular/core';
import { SkipToContentService } from '../../../services/skip-to-content.service';

export class BaseLoginComponent implements OnInit {

    constructor(
        private skipToContent: SkipToContentService
        ) {
    }

    ngOnInit() {
        this.skipToContent.skipClicked.subscribe(
            console.log("!")
            // should put focus() on input
        );

    }
}

跳至content.service:

import { Injectable, EventEmitter } from '@angular/core';

@Injectable()
export class SkipToContentService {

    skipClicked: EventEmitter<boolean> = new EventEmitter();


    constructor() {
    }

    setClicked() {
        console.log('clicked');
        this.skipClicked.emit();
    };
}

关于登录将如何 "hear" skipClicked 事件,我有点迷茫。

首先,使用BehaviorSubject代替EventEmitter。将 skipCliekd 的声明更改为以下内容:

skipClicked: BehaviorSubject<boolean> = new BehaviorSubject(false);

然后,您需要使用 next() 方法广播新值,如下所示:

this.skipClicked.next (true);

此外,将您的订阅更改为:

 this.skipToContent.skipClicked.subscribe( value => {
     if (value === true) {
         console.log("!"); 
         // should put focus() on input 
     }
 });

EventEmitter 只能在带有@Output 指令的实际组件中使用。将来可能无法使用其他任何东西。

对于亲子交流,最好使用 Subject 或 BehaviorSubject。这是 angular 指南中的示例。

https://angular.io/guide/component-interaction

@Injectable()
export class MissionService {

  // Observable string sources
  private missionAnnouncedSource = new Subject<string>();
  private missionConfirmedSource = new Subject<string>();

  // Observable string streams
  missionAnnounced$ = this.missionAnnouncedSource.asObservable();
  missionConfirmed$ = this.missionConfirmedSource.asObservable();

  // Service message commands
  announceMission(mission: string) {
    this.missionAnnouncedSource.next(mission);
  }

  confirmMission(astronaut: string) {
    this.missionConfirmedSource.next(astronaut);
  }
}

提示:

如果您有一个事件仅表示某事已发生或已完成 - 并且没有与之关联的实际数据 - 您可以使用 Subject<void>()。这使得 next() 的签名更清晰,您不需要为此提供虚拟值。

例如

windowClosed = new Subject<void>();

windowClosed.next() 将发出事件