angular 2: Korzystanie z usługi do transmisji wydarzenia
Próbuję uzyskać kliknięcie przycisku w jednym komponencie, aby skupić się na elemencie na innym komponencie. (Szczerze mówiąc, nie rozumiem, dlaczego to musi być tak skomplikowane, ale nie byłem w stanie wdrożyć prostszego sposobu, który faktycznie działa.)
Korzystam z usługi. Nie musi przekazywać żadnych danych z wyjątkiem , że nastąpiło kliknięcie. Nie jestem pewien, w jaki sposób komponent odsłuchowy ma reagować na zdarzenie.App."komponent": {]}
Przejdź do głównej content
import { Component } from '@angular/core';
import { SkipToContentService } from './services/skip-to-content.service';
export class AppComponent {
constructor(
private skipToContent: SkipToContentService
) {}
}
skipLink() {
this.skipToContent.setClicked();
}
}
Komponent logowania:
<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
);
}
}
Skip-to-content.serwis:
import { Injectable, EventEmitter } from '@angular/core';
@Injectable()
export class SkipToContentService {
skipClicked: EventEmitter<boolean> = new EventEmitter();
constructor() {
}
setClicked() {
console.log('clicked');
this.skipClicked.emit();
};
}
Jestem trochę zagubiony, jak logon "usłyszy" Zdarzenie skipClicked.
2 answers
Po pierwsze, użyj BehaviorSubject
zamiast EventEmitter
. Zmień deklarację skipCliekd
na następującą:
skipClicked: BehaviorSubject<boolean> = new BehaviorSubject(false);
Następnie musisz nadać nową wartość za pomocą metody next()
w następujący sposób:
this.skipClicked.next (true);
Również Zmień subskrypcję na:
this.skipToContent.skipClicked.subscribe( value => {
if (value === true) {
console.log("!");
// should put focus() on input
}
});
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-10-01 10:54:50
EventEmitter powinien być używany tylko w rzeczywistym komponencie z dyrektywą @ Output. Wszystko inne może nie działać w przyszłości.
Do komunikacji dziecko-rodzic lepiej jest użyć Subject lub BehaviorSubject. Jest to przykład z przewodnika kątowego.
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);
}
}
Wskazówka:
Jeśli masz zdarzenie, które oznacza, że coś się wydarzyło lub zostało ukończone - i nie ma z tym żadnych rzeczywistych danych - możesz można użyć Subject<void>()
. To sprawia, że podpis next()
jest czystszy i nie musisz podawać fałszywej wartości dla tego powodu.
Np.
windowClosed = new Subject<void>();
windowClosed.next()
będzie emitować Zdarzenie
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-20 09:12:55