AngularJS $rootScope.$on 迁移到 Angular2 的替代方案
AngularJS $rootScope.$on alternative in context of migration to Angular2
我们的 AngularJS 项目已经开始,它距离现代 Angular.
还有很长的路要走
ngMigration
实用程序建议我删除所有 $rootScope
依赖项,因为 Angular 不包含类似 $rootScope
的概念。在某些情况下它很简单,但我不知道如何使用事件订阅机制。
例如我有某种空闲看门狗:
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
如果我想摆脱 $rootScope
我必须调用 $on
函数?
UPD
问题不是关于 "how to migrate on Angular2 event system"。它是关于如何删除 $rootScope 依赖项但保留事件系统。好吧,这似乎是不可能的。
您可以实施 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
中有监听器将重置某些操作的超时
In case as bellow it listens for keyboard strokes, mouse wheel, or mouse click
constructor(
private timeoutService: TimeoutService
) {
}
@HostListener('document:keyup', ['$event'])
@HostListener('document:click', ['$event'])
@HostListener('document:wheel', ['$event'])
resetTimer () {
this.timeoutService.resetTimer();
}
I don't know what to do with event subscription mechanisms.
Angular 2+ 个框架用可观察对象替换了 $scope/$rootScope 事件总线。
来自文档:
Transmitting data between components
Angular provides an EventEmitter
class that is used when publishing values from a component. EventEmitter
extends RxJS Subject, adding an emit()
method so it can send arbitrary values. When you call emit()
, it passes the emitted value to the next()
method of any subscribed observer.
A good example of usage can be found in the EventEmitter
documentation.
有关详细信息,请参阅
我们的 AngularJS 项目已经开始,它距离现代 Angular.
还有很长的路要走ngMigration
实用程序建议我删除所有 $rootScope
依赖项,因为 Angular 不包含类似 $rootScope
的概念。在某些情况下它很简单,但我不知道如何使用事件订阅机制。
例如我有某种空闲看门狗:
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
如果我想摆脱 $rootScope
我必须调用 $on
函数?
UPD
问题不是关于 "how to migrate on Angular2 event system"。它是关于如何删除 $rootScope 依赖项但保留事件系统。好吧,这似乎是不可能的。
您可以实施 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
中有监听器将重置某些操作的超时
In case as bellow it listens for keyboard strokes, mouse wheel, or mouse click
constructor(
private timeoutService: TimeoutService
) {
}
@HostListener('document:keyup', ['$event'])
@HostListener('document:click', ['$event'])
@HostListener('document:wheel', ['$event'])
resetTimer () {
this.timeoutService.resetTimer();
}
I don't know what to do with event subscription mechanisms.
Angular 2+ 个框架用可观察对象替换了 $scope/$rootScope 事件总线。
来自文档:
Transmitting data between components
Angular provides an
EventEmitter
class that is used when publishing values from a component.EventEmitter
extends RxJS Subject, adding anemit()
method so it can send arbitrary values. When you callemit()
, it passes the emitted value to thenext()
method of any subscribed observer.A good example of usage can be found in the
EventEmitter
documentation.
有关详细信息,请参阅