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.

Author: DaveC426913, 2017-08-01

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 
     }
 });
 25
Author: Faisal,
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

 16
Author: Simon_Weaver,
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