Tabla de Contenidos
Angular
Actualize mis apuntes de programar Angular a la versión 22.
La Carpeta donde se renderiza el html y el javascript por defecto es:
dist/<project-name>/browser/
Si es que con en el navegador se pone en el URL la carpeta y no se logra ver la página por enlaces erróneos por que el href es una ruta explicita o absoluta, en archivo index.html:
<base href="/">
Se puede hacer relativa con el comando
ng build --base-href ./
Se la puede configurar una ruta absoluta con el comando:
ng build --base-href /<RUTA>/
o modificando el archivo de configuración “angular.json”:
"projects": {
"app": {
"architect": {
"build": {
"options": {
"baseHref": "/production-folder/"
}
}
}
}
}
Código básico:
//typescript import {Component} from '@angular/core'; @Component({ selector: 'app-root', imports: [], template: ` <h1>Default</h1> `, styleUrls: ['./app.css'], }) export class App { title = 'default'; }
Instalación
Primero, se debe instalar Node.js:
- Con el instalador MSI, descargar https://nodejs.org/es/download
- Por comandos por PowerShell
#Para instalar desde PowerShell: > winget install OpenJS.NodeJS
Comprobar la versión:
#Version para Node.js > node -v v24.15.0 #Versión de Npm: > npm -v 11.12.1
Instalación de Angular:
> npm install -g @angular/cli
Para ver la versión de lo instalado
> ng version ┌───────────────────────────┬───────────────────┬───────────────────┐ │ Package │ Installed Version │ Requested Version │ ├───────────────────────────┼───────────────────┼───────────────────┤ │ @angular/build │ 21.2.14 │ ^21.2.11 │ │ @angular/cli │ 21.2.14 │ ^21.2.11 │ │ @angular/common │ 21.2.16 │ ^21.2.0 │ │ @angular/compiler │ 21.2.16 │ ^21.2.0 │ │ @angular/compiler-cli │ 21.2.16 │ ^21.2.0 │ │ @angular/core │ 21.2.16 │ ^21.2.0 │ │ @angular/forms │ 21.2.16 │ ^21.2.0 │ │ @angular/localize │ 21.2.16 │ ^21.2.0 │ │ @angular/platform-browser │ 21.2.16 │ ^21.2.0 │ │ @angular/platform-server │ 21.2.16 │ ^21.2.0 │ │ @angular/router │ 21.2.16 │ ^21.2.0 │ │ @angular/ssr │ 21.2.14 │ ^21.2.11 │ │ rxjs │ 7.8.2 │ ~7.8.0 │ │ typescript │ 5.9.3 │ ~5.9.2 │ │ vitest │ 4.1.8 │ ^4.0.8 │ └───────────────────────────┴───────────────────┴───────────────────┘
Actualizar Angular:
> ng update
Using package manager: npm
Collecting installed dependencies...
Found 15 dependencies.
We analyzed your package.json, there are some packages to update:
Name Version Command to update
------------------------------------------------------------------------
@angular/cli 21.2.11 -> 22.0.0 ng update @angular/cli
@angular/core 21.2.13 -> 22.0.0 ng update @angular/core
There might be additional packages which don't provide 'ng update' capabilities that are outdated.
Crear Nuevo Proyecto
ng new <proyecto-nombre>
el comando ng new crea una carpeta y ahí carga las dependencias, en esa carpeta creada estará el proyecto, no es necesario crear la carpeta manualmente y posicionarse en esa carpeta para ejecutar el comando.
Se crean las carpetas y 232MB de archivos
/<Proyecto-Nombre>/
├─ /angular/
├─ /node_modules/
├─ /public/
│ └─ favicon.ico
└─ /src/
├── /app/
│ ├─ app.config.ts
│ ├─ app.css
│ ├─ app.html
│ ├─ app.routes.ts
│ ├─ app.spec.ts
│ └─ app.ts
├─ index.html
├─ main.ts
└─ styles.css
Tiene Tailwind como parte de opciones para manejo avanzado de CSS pero para agregar bootstrap se puede usar este comando:
ng add @ng-bootstrap/ng-bootstrap
(el ngx-bootstrap esta obsoleto y no se actualizará)
Para generar el html con la base para verla desde su dist browser (sin levantar el servidor ng serve)
ng build
Con build se crea las carpetas y archivos:
├─ /dist/ │ └─ /<nombre-proyecto>/ │ ├─ /browser/ │ │ └─ ... (archivos) │ └─ /server/ │ └─ ... (archivos)
ng build --base-href /<proyecto-nombre>/dist/<proyecto-nombre>/browser/
más información para configurar el build.
Para levantar un servidor por el puerto default 4200
ng serve
DART: Autorización con ROLES en Angular: Protege tu App como un Experto 🚀
¡ORGANIZA tus proyectos en ANGULAR 18 de esta manera!
zone.js (deprecated version angular 21), ahora se usa signals
arquitectura
El main.ts se ejecuta y lee el index.html en src:
/<Proyecto-Nombre>/
└─ /src/
├── /app/
│ │
│ ...
│
├─ index.html
├─ main.ts
└─ styles.css
- main.ts
import { bootstrapApplication } from '@angular/platform-browser'; import { appConfig } from './app/app.config'; import { App } from './app/app'; bootstrapApplication(App, appConfig) .catch((err) => console.error(err));
El css se inicia en blanco, en el html la etiqueta <app-root></app-root> se llena con el app
- index.html
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>Test</title> <base href="/"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="icon" type="image/x-icon" href="favicon.ico"> </head> <body> <app-root></app-root> </body> </html>
luego se ejecuta el app.ts en la carpeta /app/ cargando app.html y el app.css.
/<Proyecto-Nombre>/
└─ /src/
├── /app/
│ ├─ app.ts
│ ├─ app.html
│ ├─ app.css
│ ...
...
- app.ts
import { Component, signal } from '@angular/core'; import { RouterOutlet } from '@angular/router'; @Component({ selector: 'app-root', imports: [RouterOutlet], templateUrl: './app.html', styleUrl: './app.css' }) export class App { protected readonly title = signal('test'); }
lee el app.html y reemplaza el title() con el valor de readonly title.
Notas
routers, componentes, componentes stand alones
Component y Routes
el archivo “app.routes.ts”
<Proyecto-Nombre> | ├─ /app/ | ├─ app.routes.ts
El contenido por default es:
import { Routes } from '@angular/router'; export const routes: Routes = [];
Para agregar un componente se debe escribir en linea de comandos:
ng generate component <nombre o carpeta/nombre> //forma acortada: ng g c <nombre o carpeta/nombre>
Components
Los componentes son como las páginas web o segmentos web, articula el html, javascript y el CSS.
ng generate component <nombre o carpeta/nombre> //forma acortada: ng g c <nombre o carpeta/nombre>
Ejemplo
ng generate component pag/pagina_a
crea los siguientes archivos en la carpeta ./src/app/:
/<Proyecto-Nombre>/
└─ /src/
├── /app/
│ ├── /pag/
│ │ ├── /pagina-a/
│ │ │ ├─ pagina-a.css
│ │ │ ├─ pagina-a.html
│ │ │ ├─ pagina-a.spec.ts
│ │ │ └─ pagina-a.ts
│ │ ...
│ ...
...
La underline del nombre “pagina_a” en el comando, se transforma en un guion en el archivo “pagina-a.html” y en el código el nombre del objeto desaparece el guion y el underline llamado “PaginaA”.
El contenido de cada archivo:
- pagina-a.html
<p>pagina-a works!</p>
- pagina-a.spec.ts
import { ComponentFixture, TestBed } from '@angular/core/testing'; import { PaginaA } from './pagina-a'; describe('PaginaA', () => { let component: PaginaA; let fixture: ComponentFixture<PaginaA>; beforeEach(async () => { await TestBed.configureTestingModule({ imports: [PaginaA], }).compileComponents(); fixture = TestBed.createComponent(PaginaA); component = fixture.componentInstance; await fixture.whenStable(); }); it('should create', () => { expect(component).toBeTruthy(); }); });
- pagina-a.ts
import { Component } from '@angular/core'; @Component({ selector: 'app-pagina-a', imports: [], templateUrl: './pagina-a.html', styleUrl: './pagina-a.css', }) export class PaginaA {}
Routes
El archivo route está en “./src/app/app.routes.ts”
/<Proyecto-Nombre>/
└─ /src/
├── /app/
│ ├─ app.routes.ts
│ ...
...
El contenido básico es:
- app.routes.ts
import { Routes } from '@angular/router'; export const routes: Routes = [];
RouterOutlet
De la librería @angular/router en app.ts
- app.ts
import { RouterOutlet } from '@angular/router'; // <-- RouterOutlet @Component({ selector: 'app-root', imports: [RouterOutlet], // <-- RouterOutlet templateUrl: './app.html', styleUrl: './app.css' })
Ejemplo
creado el componente “pagina-a” la ruta para mostrarla se debería modificar el archivo “app.routes.ts”, no olvidar que la ruta /pag/ está
- app.routes.ts
import { Routes } from '@angular/router'; import { PaginaA } from './pag/pagina-a/pagina-a'; // <-- Agregado, importa como objeto. export const routes: Routes = [ // Agregado, path en "pag/página-a" a componente "PaginaA" { path:'pag/pagina-a', component: PaginaA } ];
con esto la dirección “pag/pagina-a” debe mostrar la página del componente.
inicio el servidor angular:
ng serve
y voy a la ruta: http://localhost:4200/pag/pagina-a
En la página “src/app/app.html”, borro el contenido por defecto y agrego los enlaces <a href=“”>
- app.html
<h1>Hello, {{ title() }}</h1> <nav> <a href="">Pagina Inicio</a> <a href="pag/pagina-a">Página A</a> </nav> <router-outlet />
/<Proyecto-Nombre>/
└─ /src/
├── /app/
│ ├── /pag/
│ │ ├── /pagina-a/
│ │ │ │
│ │ │ ...
│ │ ...
│ ...
...
RouterLink
Con RouterOutlet llena el campo <router-outlet /> con la página del componente relacionado declarada en app.routes.ts, pero RouterLink evitar recargar toda la página.
En el archivo app.ts se debe agregar RouterLink del from @angular/router, luego de RouterOutlet:
- app.ts
// antes: import { RouterOutlet } from '@angular/router'; import { RouterOutlet, RouterLink } from '@angular/router'; @Component({ selector: 'app-root', // antes: imports: [RouterOutlet], imports: [RouterOutlet, RouterLink], templateUrl: './app.html', styleUrl: './app.css' })
En versiones anteriores este código de import está en app.component.ts
Reemplazando el href y el routerLink (ojo el r en minúscula)
<!-- antes: <a href="pag/pagina-a">Página A</a> //--> <a routerLink="pag/pagina-a">Página A</a>
Ejemplo en el que usa para redireccionar en el path “” a “login”
const routes: Routes = [ {path='', redirectTo:'login', pathMatch:'full'}, {path='login', component:LoginComponent} ]
RouterLinkActive
Con RouterLinkActive, en el enlace cuya página o componente está activo, marca con un Clase para que puedas resaltarlo con CSS
En este ejemplo se le agregará la clase “activo” al link del componente activo.
- app.html
<a routerLink="pag/pag1" routerLinkActive="activo">Pag1</a>
Se tiene que agregar la funcionalidad en app.ts, en el @component:
- app.ts
import { Component, signal } from '@angular/core'; import { RouterOutlet, RouterLink, RouterLinkActive } from '@angular/router'; // <-- RouterLinkActive @Component({ selector: 'app-root', imports: [RouterOutlet, RouterLink, RouterLinkActive], // <-- RouterLinkActive templateUrl: './app.html', styleUrl: './app.css' })
<style> a{ background-color:skyblue; } a.activo{ background-color:red; } </style> el enlace tendrá el estilo de "activo"
Router
Con Router se puede ir programaticamente a un URL precargado como RouterLink
creo el botón ir a pag3 el evento onDisparar(), en este ejemplo lo agrego en app.html
Le agregué en app.ts pero es en el *.ts del componente, el evento “onDisparar()”, se debe agregar router con el constructor para poder ser llamado this.router.navigateByUrl(“/pag/pag3”)
- app.ts
import { Component, signal } from '@angular/core'; import { RouterOutlet, RouterLink, RouterLinkActive, Router } from '@angular/router'; // <-- agregado Router @Component({ selector: 'app-root', imports: [RouterOutlet, RouterLink, RouterLinkActive], templateUrl: './app.html', styleUrl: './app.css' }) export class App { protected readonly title = signal('testang'); constructor(private router: Router){} // <-- agregado para Router onDisparar(){ alert("hola") this.router.navigateByUrl("/pag/pag3") // <-- el URL //this.router.navigateByUrl(["/pag/pag3"]) //como array para meter variables? } }
Deploy
Deploy para el tipo SSR Server Side Rendering, usando Apache o Nginx
En Apache:
Usando WebPack:
Usando Hydration:
