角度服务中的 EventEmitter,好还是坏?

问题描述 投票:0回答:2

我在 Angular 服务中使用

EventEmitter
@Output
,今天一位同事提到这不是一个好的做法。

我发现这个 post 提到这是一个不好的做法,它似乎主要是个人意见,这个 answer 提到它可以使用它。 我找不到关于它的任何官方文件,所以如果有人知道官方答案,请发布。

关于EventEmittter

的官方文档
javascript angular observable angular2-services eventemitter
2个回答
10
投票

我在 Angular 服务中使用 EventEmitter 和 @Output,今天一位同事提到这不是一个好的做法。

注释

@Output()
在服务中没有效果。它用于告诉 Angular 模板编译器将
Observable
绑定到模板表达式。

如果我在服务中看到

@Output()
,那么我会告诉开发人员将其删除。

EventEmitter
是一个
Observable
在服务中使用它没有副作用,但也没有任何好处。

您可以在组件或服务中使用任何

Observable
类型的发射器。我们有
EventEmitter
的原因有两个。 1) 它早于 Angular 团队决定承诺使用可观察对象,他们认为他们可能需要自己的实现,2) 它可以在下一个 JavaScript 周期中发出值(可选设置)。

在边缘情况下,人们需要在下一个周期中发出更改以避免更改检测出现问题。

保护您的 Observables

 @Injectable()
 export class MyService {
       public events: Subject<any> = new Subject();
 }

上述服务的问题是任何人都可以从公众那里发出价值

events
。您希望您的服务成为处理发射值的唯一代码。

 @Injectable()
 export class MyService {
       private _events: Subject<any> = new Subject();
       public get events(): Observable<any> {
           return this._event.asObservable();
       }
 }

以上更好,因为对

Subject.next(..)
的访问是私有的。消费者只能订阅可观察的。

如果你遵循了 components 方法。它迫使你暴露你的发射器,这不是一个好主意。

@Injectable()
export class MyService {
       @Output()   // <<< has no effect
       public events: EventEmitter<any> = new EventEmitter();
       // ^^ makes the emitter public
}

组件如果要在模板中使用,则需要将其属性设为 public,但服务不是这样。


0
投票

从今天开始,我意识到在服务级别使用 EventEmitter 是相当糟糕的,因为当我订阅 ngInit 中的事件处理程序时,随着我不断切换页面,我的订阅会累积,并且一次 emit() 被处理 X 次订阅。

    export class XService {

        @Output() test: EventEmitter<number> = new EventEmitter<number>();
  
        public parentInitCount : number = 0;
        public childInitCount : number = 0;
    }

父组件

    constructor(private events: XService) { }

    public ngInitCounter: number = 0;

    ngOnInit() {

        this.ngInitCounter++;
        this.events.parentInitCount++;

    }

    runJob() {
        this.events.test.emit(this.ngInitCounter);
    }

孩子

    constructor(private events: XService) { }

    public ngInitCounter: number = 0;

    ngOnInit() {

        this.events.test.subscribe((value)=> { //subscriptions will accumulate going back and forth between pages, because service keeps state
            console.log('test event, parent ngInitCount: ' + value + ' child ngInitCount: ' +  this.ngInitCount);
            console.log('test event2, service ngInitCount: ' + this.events.parentInitCount + ' service child ngInitCount: ' +  this.events.childInitCount);
        });

        this.ngInitCount++;
        this.events.childInitCount++;
    }

© www.soinside.com 2019 - 2024. All rights reserved.