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



我正在尝试在一个组件中单击按钮以将焦点放在另一个组件上的元素上。(坦率地说,我不明白为什么这必须如此复杂,但我无法实现任何实际工作的更简单的方法。

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

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

跳到内容服务:

import { Injectable, EventEmitter } from '@angular/core';
@Injectable()
export class SkipToContentService {
skipClicked: EventEmitter<boolean> = new EventEmitter();

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

对于登录将如何"听到"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 指令的实际组件中。其他任何事情将来都可能不起作用。

对于子-父母的沟通,最好使用主题或行为主体。这是角度导轨的一个例子。

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()将发出事件

最新更新