3
respostas

[Sugestão] Alternativa à remoção de elementos pelo componente filho (usando @Output())

Acompanhando a aula, me preocupou um pouco o fato de o componente Pensamento deixar de ser "burro", no sentido de ter lógicas próprias. Então pensei numa alternativa, onde o pai seria avisado da alteração, e ele modificaria a lista sendo exibida. Desse modo, ficaria (um lembrete: to fazendo meu projeto em inglês):

Em PensamentoComponent (ThoughtComponent)

export class ThoughtComponent {
  //...
  @Output() favoriteUpdated = new EventEmitter();

  constructor(private thoughtService: ThoughtsService) {}

  //...

  updateFavorite(): void {
    this.thoughtService
      .updateFavoriteThought(this.thought)
      .subscribe(() => this.favoriteUpdated.emit(this.thought));
  }
}

Em ListaPensamentosComponent (ListThoughtsComponent):

export class ListThoughtsComponent implements OnInit, OnDestroy {
  listThoughts: Thought[] = [];
  currentPage = 1;
  hasMoreThoughts: boolean = true;
  filter: string = '';
  shouldListFavorites: boolean = false;
  $onDestroy = new Subject<boolean>();

  constructor(private thoughtService: ThoughtsService) {}

  //...

  onFavoriteUpdated(thought: Thought): void {
    if (this.shouldListFavorites && !thought.favorite) {
      this.listThoughts.splice(this.listThoughts.indexOf(thought), 1);
    }
  }

//...
}

E em lista-pensamentos.component.html (list-thoughts.component.html):

<section class="container">
  <!-- .... -->

  <div class="mural" *ngIf="listThoughts.length > 0; else noThoughts">
    <div *ngFor="let thought of listThoughts">
      <app-thought
        [thought]="thought"
        (favoriteUpdated)="onFavoriteUpdated($event)"
        ></app-thought>
    </div>
  </div>
</section>

<!-- .... -->

Isso eliminaria a necessidade de usr uma lista de favoritos em paralelo. Espero que seja útil e, quaisquer duvidas, olhem esse commit

3 respostas

Oi Fernando, tudo bem?

A sua sugestão é muito interessante e pode ser uma alternativa válida para o problema que está tentando resolver. A sua ideia de usar o @Output() para emitir um evento quando o favorito é atualizado é uma boa prática em Angular, pois permite que os componentes filhos comuniquem mudanças para seus componentes pais.

No seu código, você criou um EventEmitter chamado favoriteUpdated, que será acionado sempre que a função updateFavorite() for chamada. Isso vai notificar o componente pai, ListThoughtsComponent, que um pensamento favorito foi atualizado.

No geral, a sua solução parece ser uma boa alternativa para manter o componente filho "burro", ou seja, sem lógica própria, deixando a responsabilidade de gerenciar a lista de pensamentos para o componente pai.

Muito obrigada por compartilhar com a gente.

Um abraço e bons estudos.

Obrigado! Inclusive, pensando agora, dá pra tirar também a lógica de atualização do serviço de dentro do componente Pensamento, e usar o emitter pra fazer isso a partir do pai. Depois mando aqui essa atualização

Aqui está a atualização:

Em thought.component.html:

    <button class="botao-favorito" (click)="updateFavorite()">
      <img
        src="/assets/imagens/icone-favorito-{{ changeFavoriteIcon() }}.png"
        alt="favorito {{ changeFavoriteIcon() }}"
        srcset=""
      />
    </button>

Em thought.component.ts:

  updateFavorite(): void {
    this.favoriteUpdated.emit(this.thought);
  }

Em list-thoughts.component.ts:

  onFavoriteUpdated(thought: Thought): void {
    this.thoughtService.updateFavoriteThought(thought).subscribe(() => {
      if (this.isListingFavorites && !thought.favorite) {
        this.listThoughts.splice(this.listThoughts.indexOf(thought), 1);
      }
    });
  }

Pode ser encontrado nesse commit