angular - 是否需要取消订阅@Output EventEmitter

标签 angular typescript

在 Angular 网站上,他们有一个父子组件使用 @Output() onVoted = new EventEmitter<boolean>(); 相互交谈的示例。 .见下文。

在这个给定的示例中,您是否需要取消订阅 EventEmitter 以防止内存泄漏/膨胀?还是框架会为您处理这些?

组件交互/src/app/voter.component.ts

import { Component, EventEmitter, Input, Output } from '@angular/core';

@Component({
  selector: 'app-voter',
  template: `
    <h4>{{name}}</h4>
    <button (click)="vote(true)"  [disabled]="voted">Agree</button>
    <button (click)="vote(false)" [disabled]="voted">Disagree</button>
  `
})
export class VoterComponent {
  @Input()  name: string;
  @Output() onVoted = new EventEmitter<boolean>();
  voted = false;

  vote(agreed: boolean) {
    this.onVoted.emit(agreed);
    this.voted = true;
  }
}

组件交互/src/app/votetaker.component.ts

import { Component }      from '@angular/core';

@Component({
  selector: 'app-vote-taker',
  template: `
    <h2>Should mankind colonize the Universe?</h2>
    <h3>Agree: {{agreed}}, Disagree: {{disagreed}}</h3>
    <app-voter *ngFor="let voter of voters"
      [name]="voter"
      (onVoted)="onVoted($event)">
    </app-voter>
  `
})
export class VoteTakerComponent {
  agreed = 0;
  disagreed = 0;
  voters = ['Mr. IQ', 'Ms. Universe', 'Bombasto'];

  onVoted(agreed: boolean) {
    agreed ? this.agreed++ : this.disagreed++;
  }
}

最佳答案

如果您在 Angular 网站上看到示例并且他们没有取消订阅,那么您认为您为什么应该取消订阅?

Angular 会处理它。

当它创建指令实例时,它会订阅输出:

if (def.outputs.length) {
    for (let i = 0; i < def.outputs.length; i++) {
      const output = def.outputs[i];
      const subscription = instance[output.propName !].subscribe(
          eventHandlerClosure(view, def.parent !.nodeIndex, output.eventName));
      view.disposables ![def.outputIndex + i] = subscription.unsubscribe.bind(subscription);

https://github.com/angular/angular/blob/235a235fab45b2c82f8758fc9c0779f62a5b6c04/packages/core/src/view/provider.ts#L138-L140

当它销毁组件时,它也会自动取消订阅输出订阅:

export function destroyView(view: ViewData) {
  ...
  if (view.disposables) {
    for (let i = 0; i < view.disposables.length; i++) {
      view.disposables[i]();

所以每次你销毁你的指令时,angular 都会为你处理所有订阅。

但是,如果您在代码中手动订阅 EventEmitter,那么您必须自行取消订阅。

关于angular - 是否需要取消订阅@Output EventEmitter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48759538/

相关文章:

angular - WebStorm 是如何识别 Angular 语言服务的?

angular - 如何在 Angular 2 中监听点击并按住?

angular - 如何在无限行模型中设置初始起始页?

html - Angular2设置输入字段的最小值和最大值

typescript - 如何使用 Gulp 和 SystemJS 捆绑 Angular 2 Typescript 应用程序?

javascript - Material-UI 中的 DefaultTheme 导致 `Invalid module name in augmentation` 错误

javascript - 在 Angular 4 中使用依赖注入(inject)扩展类

Angular 使用 API 调用中的 JSON 数据

angular - 带有访客组件的父子组件树

javascript - 访问 Angular 2 中的 DOM 元素并更改元素的类属性