Альтернатива AngularJS $rootScope.$on в контексте перехода на Angular2

Наш проект AngularJS начал долгий путь к современному Angular.

Утилита ngMigration рекомендует мне удалить все зависимости $rootScope, потому что Angular не содержит аналогичной концепции, такой как $rootScope. В некоторых случаях это довольно просто, но я не знаю, что делать с механизмами подписки на события.

Например, у меня есть какой-то сторожевой таймер Idle:

angular
    .module('myModule')
    //...
    .run(run)

//...       
function run($rootScope, $transitions, Idle) {
    $transitions.onSuccess({}, function(transition) {
        //...
        Idle.watch(); // starts watching for idleness
    });

    $rootScope.$on('IdleStart', function() {
        //...
    });

    $rootScope.$on('IdleTimeout', function() {
        logout();
    });
}

На каком объекте вместо $rootScope я должен вызвать функцию $on, если я хочу избавиться от $rootScope?

UPD

Вопрос был не о том, "как мигрировать в систему событий Angular2". Речь шла о том, как удалить зависимости $rootScope, но сохранить систему событий. Ну, это кажется невозможным.


person kirill.login    schedule 03.12.2019    source источник
comment
Отвечает ли это на ваш вопрос? Angular 2 — что эквивалентно корневой области?   -  person Andris    schedule 03.12.2019
comment
Сервисы рекомендуются в последних версиях Angular.   -  person Andris    schedule 03.12.2019
comment
Это не совсем тот ответ, который мне нужен. Но теперь я понял, что в AngularJS невозможно иметь механизм событий и одновременно не иметь $scope и $rootScope. Это сложная спаренная вещь.   -  person kirill.login    schedule 04.12.2019
comment
Привет. У меня точно такой же вопрос: удалить использование rootscope в приложении AngularJS, чтобы его было легко обновить. В частности, как обрабатывать события без области/rootScope   -  person AshD    schedule 04.02.2020


Ответы (2)


Я не знаю, что делать с механизмами подписки на события.

Фреймворки Angular 2+ заменяют шину событий $scope/$rootScope наблюдаемыми объектами.

Из документов:

Передача данных между компонентами

Angular предоставляет класс EventEmitter, который используется при публикации значений из компонента. EventEmitter расширяет тему RxJS, добавляя emit(), чтобы он мог отправлять произвольные значения. Когда вы вызываете emit(), он передает испускаемое значение методу next() любого подписанного наблюдателя.

Хороший пример использования можно найти в документации EventEmitter.

Для получения дополнительной информации см.

person georgeawg    schedule 03.12.2019

Вы можете реализовать TimeOutService, который будет выходить из системы через x минут (в данном случае 15 минут) бездействия или сбросит таймер после определенных действий.

import { Injectable, OnDestroy } from '@angular/core';
import { Router } from '@angular/router';
import { Observable, Subject, Subscription, timer } from 'rxjs';
import { startWith, switchMap } from 'rxjs/operators';

import { AuthService } from 'path/to/auth.service';

@Injectable()
export class TimeoutService implements OnDestroy {

  limitMinutes = 15;
  secondsLimit: number = this.limitMinutes * 60;
  private reset$ = new Subject();
  timer$: Observable<any>;
  subscription: Subscription;

  constructor(private router: Router,
              private authService: AuthService,
  ) {
  }

  startTimer() {
    this.timer$ = this.reset$.pipe(
      startWith(0),
      switchMap(() => timer(0, 1000))
    );
    this.subscription = this.timer$.subscribe((res) => {
      if (res === this.secondsLimit) {
        this.logout();
      }
    });
  }

  resetTimer() {
    this.reset$.next(void 0);
  }

  endTimer() {
    if (typeof this.subscription !== 'undefined') {
      this.subscription.unsubscribe();
    }

  }

  logout(): boolean {
    this.authService.signOut().subscribe((res) => {
      this.subscription.unsubscribe();
    });
    return false;
  }

  ngOnDestroy():void {
    this.subscription.unsubscribe();
  }
}

И в AppComponent есть слушатель, который сбрасывает тайм-аут на определенные действия.

В случае, как показано ниже, он прослушивает нажатия клавиш, колесо мыши или щелчок мыши.

 constructor(
    private timeoutService: TimeoutService
  ) {
  }

  @HostListener('document:keyup', ['$event'])
  @HostListener('document:click', ['$event'])
  @HostListener('document:wheel', ['$event'])
  resetTimer () {
    this.timeoutService.resetTimer();
  }
person mxr7350    schedule 03.12.2019