角度2:使用服务来广播事件

Dav*_*913 19 service eventemitter angular

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

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

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

}
Run Code Online (Sandbox Code Playgroud)

登录组件:

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

    }
}
Run Code Online (Sandbox Code Playgroud)

跳跃到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();
    };
}
Run Code Online (Sandbox Code Playgroud)

关于登录将如何"听到"skipClicked事件,我在这里有点迷失.

Fai*_*sal 17

只需在setClicked()方法中进行一些小改动:

this.skipClicked.next(true);

代替 BehaviorSubject

将您的订阅更改为:

skipClicked: BehaviorSubject<boolean> = new BehaviorSubject(false);
Run Code Online (Sandbox Code Playgroud)

这将解决您的问题.


Sim*_*ver 13

EventEmitter只能在具有@Output指令的实际组件中使用.其他任何东西将来都可能无效.

对于子父沟通,最好使用Subject或BehaviorSubject.这是角度指南的一个例子.

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);
  }
}
Run Code Online (Sandbox Code Playgroud)

小费:

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

例如.

windowClosed = new Subject<void>();
Run Code Online (Sandbox Code Playgroud)

windowClosed.next() 将发出该事件