Listas con scroll
Clase 17 de 24 • Curso de Maquetación con Angular CDK y Tailwind CSS
Contenido del curso
Clase 17 de 24 • Curso de Maquetación con Angular CDK y Tailwind CSS
Contenido del curso
Carlos Mario Ortiz Moreno
José Nicolás Aristizabal Ramírez
MATEO FLOREZ ARROYO
Brenda Sutara
Max Andy Diaz Neyra
Reinaldo Mendoza
Jorge Morales
Para los que estan en angular 18 y HttpClientModule ya esta en desuso para hacer la peticion http tienen que ir a app.config.ts y poner el providers provideHttpClient de la siguiente manera :
import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';import { provideRouter } from '@angular/router'; import { routes } from './app.routes';import { provideHttpClient } from '@angular/common/http'; export const appConfig: ApplicationConfig = { providers: [provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes), provideHttpClient()]};
y listo, desde el componente ya se puede hacer peticiones http.
Como buena práctica es recomendable separar las funcionalidades segú el uso, para el caso de las peticiones http deberiamos crear un servicio con ng y para el caso de las interfaces deberiamos incluirlas dentro de nuestra carpeta models.
<div class="flex flex-col h-screen"> <app-navbar></app-navbar> <div class="w-full grow bg-sky-600 p-6"> <div class="flex gap-4"> <div class="w-1/2"> <h1 class="text-white">List A (Normal scroll)</h2> <div class="h-64 w-full border overflow-y-scroll bg-white rounded mt-2"> <div class="flex items-center space-x-4" *ngFor="let product of products"> <img class="w-10 h-10 rounded-full" [src]="product.images[0]" alt=""> <div class="space-y-1 font-medium dark:text-white"> <div>{{ product.title }}</div> <div class="text-sm text-gray-500 dark:text-gray-400">${{product.price}}</div> </div> </div> </div> </div> <div class="w-1/2"> <h1 class="text-white">List B (Virtual scroll)</h2> </div> </div> </div> </div>
En la nueva versión de angular no tenemos el archivo app.module.ts Directamente lo incorporamos en el .ts del componente o la página que creamos. Dejo mi código a continuación, también cambió la forma de escribir los *ngFor pero se puede utilizar la antigua, eso no afecta en nada
archivo scroll.component.ts
import { Component } from '@angular/core'; import {ScrollingModule} from '@angular/cdk/scrolling'; import { CommonModule } from '@angular/common'; import { NavbarComponent } from '../../components/navbar/navbar.component'; import { HttpClient, HttpClientModule } from '@angular/common/http'; interface Product { id: string; title: string; price: string; images: string[]; } @Component({ selector: 'app-scroll', standalone: true, imports: [CommonModule, ScrollingModule, NavbarComponent, HttpClientModule], templateUrl: './scroll.component.html' }) export class ScrollComponent { products: Product[] = []; constructor( private http: HttpClient ) { } ngOnInit(): void { this.http.get<Product[]>('https://api.escuelajs.co/api/v1/products') .subscribe(data => { this.products = data; }) } }
archivo scroll.component.html
<div class="felx flex-col h-screen"> <app-navbar></app-navbar> <div class="w-full grow bg-sky-600 p-6 h-full"> <div class="flex gap-4"> <div class="w-1/2"> <div class="text-white"> <h2>List A (Normal scroll)</h2> <div class="h-64 w-full border overflow-y-scroll bg-white rounded-lg mt-2"> @for (product of products; track product.id) { <div class="flex items-center gap-4" > <img class="w-10 h-10 rounded-full" [src]="product.images[0]" alt=""> <div class="font-medium dark:text-white"> <div>{{ product.title }}</div> <div class="text-sm text-gray-500 dark:text-gray-400">{{ product.price }}</div> </div> </div> } </div> </div> </div> <div class="w-1/2"> <div class="text-white"> <h2>List B (Virtual scroll)</h2> </div> </div> </div> </div> </div>
Excelente aporte dejo mi codigo version Angular 19: archivo scroll.component.ts
import { Component, inject } from '@angular/core'; import { rxResource } from '@angular/core/rxjs-interop'; import { NavbarComponent } from '../../components/navbar/navbar.component'; import { ProductService } from '../../services/product.service'; @Component({ selector: 'app-scroll', imports: [NavbarComponent], templateUrl: './scroll.component.html', }) export class ScrollComponent { private productService = inject(ProductService); products = rxResource({ loader: () => this.productService.getProducts(), }); }
archivo scroll.component.html
<div class="flex flex-col h-screen"> <app-navbar></app-navbar> <div class="w-full grow bg-sky-600 p-6 h-full"> <div class="flex gap-4"> <div class="w-1/2"> <div class="text-white"> <h3>List A (Normal scroll)</h3> <div class="h-64 w-full border overflow-y-auto bg-white rounded mt-2"> @for (product of products.value(); track product.id) { <div class="flex items-center gap-4"> <img class="w-10 h-10 rounded-full" [src]="product.images[0]" alt="" /> <div class="font-medium dark:text-white"> <div class="text-black">{{ product.title }}</div> <div class="text-sm text-gray-500 dark:text-gray-400"> {{ product.price }} </div> </div> </div> } </div> </div> </div> <div class="w-1/2"> <div class="text-white"> <h3>List B (Virtual scroll)</h3> </div> </div> </div> </div> </div>
servicio:
import { HttpClient } from '@angular/common/http'; import { inject, Injectable } from '@angular/core'; interface Product { id: string; title: string; price: string; images: string[]; } @Injectable({ providedIn: 'root', }) export class ProductService { private http = inject(HttpClient); getProducts() { return this.http.get<Product[]>('https://api.escuelajs.co/api/v1/products'); } }
Llegamos al punto dulce del curso
scroll.component.ts
import { Component, inject, signal } from '@angular/core'; import { NavbarComponent } from '../../components/navbar/navbar.component'; import { CommonModule } from '@angular/common'; import { ProductService } from '../../services/product.service'; interface Product { id: string; title: string; price: string; images: string[]; } @Component({ selector: 'app-scroll', standalone: true, imports: [CommonModule, NavbarComponent], templateUrl: './scroll.component.html', }) export class ScrollComponent { products: Product[] = []; private productService = inject(ProductService); constructor() {} ngOnInit() { this.getProducts(); } private getProducts(): void { this.productService.getProducts().subscribe((data) => { this.products = data; }); } } ```**product.service.ts** ```js import { HttpClient } from '@angular/common/http'; import { Injectable, inject } from '@angular/core'; interface Product { id: string; title: string; price: string; images: string[]; } @Injectable({ providedIn: 'root', }) export class ProductService { private http = inject(HttpClient); constructor() {} getProducts() { const url = new URL(`https://api.escuelajs.co/api/v1/products`); return this.http.get<Product[]>(url.toString()); } }