🧩 Exercícios Práticos: Ciclo de Vida e Hooks Modernos (afterRender, afterNextRender)

Spec Frontend Com Angular • Trilha Progressiva em 4 Níveis


🎯 Nível 1: Fundamentos

Problema 07.1 — Hooks Tradicionais: ngOnInit e ngOnDestroy

Contexto: Hooks Tradicionais: ngOnInit e ngOnDestroy no contexto de Ciclo de Vida e Hooks Modernos (afterRender, afterNextRender).

Requisitos de Execução:

  1. Inicializar recursos no ngOnInit e cancelar inscrições no ngOnDestroy.

Resultado Esperado

Ciclo de vida do componente gerenciado com interfaces explícitas.

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_07_1_SeuNome
  2. Envie na tarefa: Atividade Cap 07 - Ciclo de Vida e Hooks Modernos (afterRender, afterNextRender)
🔑 Gabarito de Código & Solução Comentada
// lifecycle-tradicional.component.ts
import { Component, OnInit, OnDestroy } from '@angular/core';

@Component({
  selector: 'app-lifecycle-demo',
  standalone: true,
  template: `<p>Componente Ativo</p>`
})
export class LifecycleDemoComponent implements OnInit, OnDestroy {
  ngOnInit() { console.log('Componente inicializado no ngOnInit'); }
  ngOnDestroy() { console.log('Componente destruído no ngOnDestroy'); }
}

🔍 Nível 2: Prática

Problema 07.2 — Hooks Modernos de Renderização com afterRender e afterNextRender

Contexto: Hooks Modernos de Renderização com afterRender e afterNextRender no contexto de Ciclo de Vida e Hooks Modernos (afterRender, afterNextRender).

Requisitos de Execução:

  1. Utilizar afterNextRender(() => ...) para inicializar biblioteca de gráficos de terceiros no canvas do DOM.

Resultado Esperado

Manipulação do DOM executada de forma segura apenas após a renderização completa no navegador.

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_07_2_SeuNome
  2. Envie na tarefa: Atividade Cap 07 - Ciclo de Vida e Hooks Modernos (afterRender, afterNextRender)
🔑 Gabarito de Código & Solução Comentada
// chart-render.component.ts
import { Component, ElementRef, ViewChild, afterNextRender } from '@angular/core';

@Component({
  selector: 'app-chart-render',
  standalone: true,
  template: `<canvas #chartCanvas></canvas>`
})
export class ChartRenderComponent {
  @ViewChild('chartCanvas') canvas!: ElementRef<HTMLCanvasElement>;

  constructor() {
    afterNextRender(() => {
      console.log('Canvas pronto para desenho:', this.canvas.nativeElement.width);
    });
  }
}

⚡ Nível 3: Integração

Problema 07.3 — Detecção de Mudanças Estrita com ChangeDetectionStrategy.OnPush

Contexto: Detecção de Mudanças Estrita com ChangeDetectionStrategy.OnPush no contexto de Ciclo de Vida e Hooks Modernos (afterRender, afterNextRender).

Requisitos de Execução:

  1. Configurar componente com @Component({ changeDetection: ChangeDetectionStrategy.OnPush }) e Signals.

Resultado Esperado

Renderizações redundantes eliminadas com estratégia OnPush estrita.

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_07_3_SeuNome
  2. Envie na tarefa: Atividade Cap 07 - Ciclo de Vida e Hooks Modernos (afterRender, afterNextRender)
🔑 Gabarito de Código & Solução Comentada
// on-push-demo.component.ts
import { Component, ChangeDetectionStrategy, input } from '@angular/core';

@Component({
  selector: 'app-on-push-card',
  standalone: true,
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `<div>{{ valor() }}</div>`
})
export class OnPushCardComponent {
  valor = input.required<number>();
}

🏆 Nível 4: Desafio Corporativo

Problema 07.4 — Limpeza Automática de Inscrições com takeUntilDestroyed()

Contexto: Limpeza Automática de Inscrições com takeUntilDestroyed() no contexto de Ciclo de Vida e Hooks Modernos (afterRender, afterNextRender).

Requisitos de Execução:

  1. Utilizar operador RxJS takeUntilDestroyed() eliminando a necessidade de ngOnDestroy manual.

Resultado Esperado

Inscrição RxJS cancelada automaticamente no descarte do componente.

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_07_4_SeuNome
  2. Envie na tarefa: Atividade Cap 07 - Ciclo de Vida e Hooks Modernos (afterRender, afterNextRender)
🔑 Gabarito de Código & Solução Comentada
// auto-cleanup.component.ts
import { Component } from '@angular/core';
import { interval } from 'rxjs';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';

@Component({
  selector: 'app-auto-cleanup',
  standalone: true,
  template: `<p>Timer ativo com auto-cleanup</p>`
})
export class AutoCleanupComponent {
  constructor() {
    interval(1000)
      .pipe(takeUntilDestroyed())
      .subscribe(v => console.log('Tick:', v));
  }
}