J'essaie d'obtenir un clic de bouton dans un composant pour mettre l'accent sur un élément d'un autre composant. (Franchement, je ne comprends pas pourquoi cela doit être si complexe, mais je n'ai pas été en mesure de mettre en œuvre une méthode plus simple qui fonctionne réellement.)
J'utilise un service. Il n'a pas besoin de transmettre de données sauf que le clic s'est produit. Je ne sais pas comment le composant d'écoute est censé répondre à l'événement.
app.component:
Passer au contenu principal
import { Component } from '@angular/core';
import { SkipToContentService } from './services/skip-to-content.service';
export class AppComponent {
constructor(
private skipToContent: SkipToContentService
) {}
}
skipLink() {
this.skipToContent.setClicked();
}
}
composant de connexion:
<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.service:
import { Injectable, EventEmitter } from '@angular/core';
@Injectable()
export class SkipToContentService {
skipClicked: EventEmitter<boolean> = new EventEmitter();
constructor() {
}
setClicked() {
console.log('clicked');
this.skipClicked.emit();
};
}
Je suis un peu perdu ici quant à la façon dont la connexion "entendra" l'événement skipClicked.
Faites juste un petit changement dans votre méthode setClicked ():
this.skipClicked.next (true);
au lieu de this.skipClicked.emit();
Modifiez votre abonnement en:
this.skipToContent.skipClicked.subscribe( value => { if (value === true) { console.log("!"); // should put focus() on input } });
Cela résoudra votre problème.
Pour la communication enfant-parent, il est préférable d'utiliser un objet ou un sujet comportemental. Ceci est un exemple du guide 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);
}
}
Si vous avez un événement qui signifie simplement que quelque chose s'est produit ou terminé - et qu'aucune donnée réelle ne lui est associée - vous pouvez utiliser une Subject<void>()
. Cela rend la signature de next()
plus propre et vous n'avez pas besoin de fournir une valeur fictive pour le plaisir.
Par exemple.
windowClosed = new Subject<void>();
windowClosed.next()
va émettre l'événement