Solucionado (ver solução)
Solucionado
(ver solução)
4
respostas

Como adicionar um progressSpine para cada card

Alguém teria uma ideia de como adicionar um progressSpinner para cada card de forma que cada Spinner pertencesse ao seu card, caso o card que fosse carregado na tela primeiro liberava o card que teria um link no card e eu poderi clicar no card que finalizou o carregamento. Enquanto os demais cards estavam carregando e com o Spinner ainda?

4 respostas
solução!

Oii, Sergio. Tudo bem?

Pra incluir o recurso de progress spinner no projeto do curso, precisamos seguir alguns passos e, seria necessário até mesmo, criar um vídeo extra para facilitar. Mas, para te ajudar a entender melhor como isso pode ser feito, preparei um tutorial em formato de texto para um novo projeto Angular.

Isso pode servir como uma base caso você decida implementar essa funcionalidade no projeto do curso. Seria até um desafio extra caso queira explorar novos recursos e aprimorar suas habilidades. A seguir, o passo a passo:

  • Utilizaremos o Angular Material, que oferece um componente de progress spinner que é super útil para essa tarefa.
  • Criar um novo projeto:
ng new card-spinner-app
cd card-spinner-app
  • Adicionar Angular Material
ng add @angular/material
  • Criar um novo componente:
ng generate component card-spinner
  • Substitua o conteúdo do arquivo card-spinner.component.ts com o seguinte código:
import { Component, OnInit } from '@angular/core';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { MatCardModule } from '@angular/material/card';
import { CommonModule } from '@angular/common'; // Importe o CommonModule

@Component({
  selector: 'app-card-spinner',
  standalone: true,
  imports: [CommonModule, MatProgressSpinnerModule, MatCardModule], // Adicione o CommonModule aqui
  templateUrl: './card-spinner.component.html',
  styleUrls: ['./card-spinner.component.css']
})
export class CardSpinnerComponent implements OnInit {
  cards = [
    { content: 'https://teste.com/1', loading: true },
    { content: 'https://teste.com/2', loading: true },
    { content: 'https://teste.com/3', loading: true }
  ];

  ngOnInit() {
    this.cards.forEach(card => {
      setTimeout(() => {
        card.loading = false;
      }, Math.random() * 5000);
    });
  }
}
  • Substitua o conteúdo do arquivo card-spinner.component.html com o seguinte:
<div style="display: flex; flex-wrap: wrap; gap: 16px;">
    <mat-card *ngFor="let card of cards">
      <div *ngIf="card.loading">
        <mat-spinner></mat-spinner>
      </div>
      <div *ngIf="!card.loading">
        <a href="{{ card.content }}" target="_blank">{{ card.content }}</a>
      </div>
    </mat-card>
  </div>
  • Você pode adicionar um estilo simples, se desejar. No card-spinner.component.css, adicione:
mat-card {
    width: 200px;
    height: 150px;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  • Abra o arquivo app.component.ts e certifique-se de que o novo componente tá declarado:
import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { CardSpinnerComponent } from './card-spinner/card-spinner.component';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [RouterOutlet, CardSpinnerComponent],
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'card-spinner-app';
}
  • Agora, para exibir o novo componente, atualize o arquivo app.component.html para incluir o seletor do novo componente:
<app-card-spinner></app-card-spinner>
  • Finalmente, reinicie o servidor para aplicar as mudanças:
ng serve

Nesse código, implementamos um componente que exibe uma lista de cards, cada um com um progress spinner que é mostrado enquanto o card tá carregando. Usamos Angular Material para estilizar os componentes, e a lógica do carregamento é feita com um método ngOnInit que simula um atraso. Assim, quando o carregamento de um card é finalizado, o spinner desaparece e o link se torna clicável.

Resultado:

GIF que mostra o resultado do projeto acima, mostrando o carregando com um spinner progress em três cards

Espero ter ajudado.

Um abraço e bons estudos.

é assim mesmo lorena, voce poderia disponibilizar o codigo-fonte? por causa das dependências tipo o animation e outros que o angular precisa, obrigado pela dica. No meu caso uso o Angular 9 e não funcionou com esse código, alguns trechos dão erro, por exemplo:

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Com o Angular 9, nesse arquivo card-spinner.component.ts o standalone e imports já da erro

vou te passar o código meu aqui:

card-spinner.component.ts

import { Component, OnInit } from '@angular/core';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { MatCardModule } from '@angular/material/card';
import { CommonModule } from '@angular/common'; // Importe o CommonModule

@Component({
  selector: 'app-card-spinner',
  //standalone: true,
  //imports: [CommonModule, MatProgressSpinnerModule, MatCardModule], // Adicione o CommonModule aqui
  templateUrl: './card-spinner.component.html',
  styleUrls: ['./card-spinner.component.css']
})
export class CardSpinnerComponent implements OnInit {
  cards = [
    { content: 'https://teste.com/1', loading: true },
    { content: 'https://teste.com/2', loading: true },
    { content: 'https://teste.com/3', loading: true }
  ];

  ngOnInit() {
    this.cards.forEach(card => {
      setTimeout(() => {
        card.loading = false;
      }, Math.random() * 5000);
    });
  }
}

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { CardSpinnerComponent } from './card-spinner/card-spinner.component';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { MatCardModule } from '@angular/material/card';
import { CommonModule } from '@angular/common'; // Importe o CommonModule


import { BrowserAnimationsModule } from '@angular/platform-browser/animations';


@NgModule({
  declarations: [
    AppComponent,CardSpinnerComponent
  ],
  imports: [ BrowserModule, BrowserAnimationsModule, MatProgressSpinnerModule, MatCardModule, CommonModule
  ],
  providers: [AppRoutingModule  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

Usei Angular 9 e nem aparece nada na tela, chega nem no breakpoint, é como se o código nem executasse

Oi, Sergio. Tudo bem?

Para usar certas funcionalidades, como os standalone components, é necessário ter uma versão recente do Angular. Verifique e atualize para a versão 17.3.11 ou superior conforme listado:

  • Angular CLI: 17.3.8
  • Angular: 17.3.11
  • Node.js: 20.15.1
  • Angular Material: 17.3.10

A atualização do Angular não só proporciona novas funcionalidades, mas também melhora a performance e a segurança da aplicação.

Código-fonte no GitHub

Para facilitar, aqui está o código completo no GitHub.

Espero ter ajudado.

Um abraço e bons estudos.

Tá certo Lorena, obrigado, me ajudou muito, desenvolvo para uma estatal e lá usamos o Angular 9, como sao muitos softwares que são interligados, é complicado mudar as versões.