Angular EventEmitter вызывается несколько раз - PullRequest
0 голосов
/ 27 ноября 2018

Это действительно странно и трудно объяснить.Я использовал EventEmitter в некоторых своих службах и использовал его для изменения данных в моих представлениях.У меня возникла проблема с маршрутами изменения (по ссылкам или через историю), когда она запускалась несколько раз, и из-за этого она испортила мою логику.

Поэтому я создал тест на stackblitz, чтобы увидетьесли бы я мог воссоздать это.Я сделал простую услугу:

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

@Injectable()
export class ListService {
@Output() listChanged: EventEmitter<any[]> = new EventEmitter<any[]>()

  constructor() { }

  list() {
    this.listChanged.emit([]);
  }
}

, а затем на одном из своих маршрутов я просто делаю это:

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

import { ListService } from '../list.service';

@Component({
  selector: 'app-products',
  templateUrl: './products.component.html',
  styleUrls: ['./products.component.css']
})
export class ProductsComponent implements OnInit {
  count: any[] = []

  constructor(
    private listService: ListService
  ) { }

  ngOnInit() {
    this.listService.listChanged.subscribe(() => {
      this.count.push('invoked');
      console.log('invoked');
      console.log('------');
    });
    this.listService.list();
  }
}

И затем я создал простой шаблон, подобный этому:

<p>
  Invoke should only be called once
</p>

<ul>
  <li *ngFor="let item of count">{{ item }}</li>
</ul>

Когда вы перемещаетесь между маршрутами, похоже, что он работает должным образом ( ngFor должен иметь только один элемент), но если вы откроете консоль и посмотрите, вы увидитеобратите внимание, что каждый раз, когда вы переходите от одного вида и обратно, он запускает дополнительное время.

  • Итак, при первом посещении вы увидите выход консоли один раз.
  • Очистите консоль иперемещайтесь между представлениями, и вы увидите вывод консоли дважды.
  • Очистите консоль и перейдите между представлениями, и вы увидите вывод консоли три раза .....

Это будетпродолжайте происходить каждый раз, когда вы меняете взгляды.Вот ссылка на стек, поэтому вы можете увидеть ее сами.

https://stackblitz.com/edit/angular-sthags

Может кто-нибудь сказать мне, почему это происходит и как это остановить?

1 Ответ

0 голосов
/ 27 ноября 2018

Это потому, что вы не убиваете подписку, когда ваш компонент разрушается (вызывая утечку памяти, создавая новые подписки при каждой инициализации компонента Products)

Чтобы назначить подписку переменной класса, используйте ngOnDestroy()зацепить убить подписку.

subsVar: Subscription;

ngOnInit() {
    this.subsVar = this.listService.listChanged.subscribe(() => {
      this.count.push('invoked');
      console.log('invoked');
      console.log('------');
    });
}

ngOnDestroy() {
   if (this.subsVar) {
      this.subsVar.unsubscribe()
    }
}

https://stackblitz.com/edit/angular-9rvxgv?file=src/app/products/products.component.ts

...