Angular 角度2:使用服务广播事件
我试图在一个组件中点击一个按钮,将焦点放在另一个组件上的一个元素上。(坦率地说,我不明白为什么这会如此复杂,但我还没有实现任何实际可行的更简单的方法。) 我正在使用一个服务。它不需要传递任何数据,除非发生了单击。我不确定监听组件是如何响应事件的 应用程序组件:Angular 角度2:使用服务广播事件,angular,service,eventemitter,Angular,Service,Eventemitter,我试图在一个组件中点击一个按钮,将焦点放在另一个组件上的一个元素上。(坦率地说,我不明白为什么这会如此复杂,但我还没有实现任何实际可行的更简单的方法。) 我正在使用一个服务。它不需要传递任何数据,除非发生了单击。我不确定监听组件是如何响应事件的 应用程序组件: <input type="text" name="username" /> import { Component, OnInit } from '@angular/core'; import { SkipToContent
<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 { 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
);
}
}
从“@angular/core”导入{Component,OnInit};
从“../../../services/skip到content.service”导入{SkipToContentService};
导出类BaseLoginComponent实现OnInit{
建造师(
私有skipToContent:SkipToContentService
) {
}
恩戈尼尼特(){
this.skipToContent.skipClicked.subscribe(
控制台日志(“!”)
//应该将focus()放在输入上
);
}
}
跳到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();
};
}
从'@angular/core'导入{Injectable,EventEmitter};
@可注射()
导出类SkipToContentService{
skipClicked:EventEmitter=新的EventEmitter();
构造函数(){
}
setClicked(){
console.log('clicked');
this.skipClicked.emit();
};
}
关于登录如何“听到”skipClicked事件,我在这里有点不知所措。首先,使用
行为主体
而不是事件发射器
。将skipCliekd
的声明更改为以下内容:
skipClicked: BehaviorSubject<boolean> = new BehaviorSubject(false);
另外,将您的订阅更改为:
this.skipToContent.skipClicked.subscribe( value => {
if (value === true) {
console.log("!");
// should put focus() on input
}
});
EventEmitter应仅在带有@Output指令的实际组件中使用。其他任何东西在将来都可能行不通。 对于儿童-家长沟通,最好使用主题或行为主题。这是一个来自角度引导的示例
windowClosed.next()
将发出事件一些问题:1]“GeneratorNext不是函数”在SafeSubscriber.schedulerFn[as _next](event _emitter.ts:115)2]事件在页面加载时自动触发。i、 我得到的第一件事是“!”。3] 据我所知,next()不推荐使用emit()EventEmmiter,只在componentEventEmitter中使用,应该只在实际组件中使用,Angular component integration Guide建议使用共享服务,如另一个答案所示,因此,由于答案需要更新或误导他人,所以不应在服务中使用EventEmitter
。使用共享服务来广播活动:是的,当我只需要这项服务来做一件事的时候,我也真的很难过。我该给它取什么名字呢?它是以组件命名的,还是以动作命名的,还是以动作类型命名的。我想你只需要看看什么对你有用。另一件需要记住的关键事情是,你可以将用于内部数据传输的服务组合起来。它们可以相互注入,如果您有一个包含5个不相关子项的复杂控件,则可以注入5个您想要的服务。我希望他们有一个比“服务”更好的名字
@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);
}
}
windowClosed = new Subject<void>();