Angular
Angular basics
Angular Router Jumpstart
Angular
- Web oficial
- Ventajas
- 5 ventajas
- llibre
- Tutorials Digital Ocean Angular
- Setup
- Guide Quick Start
- Style Guide
- Buenas Prácticas: curso escuela it
- Buenas Prácticas
- Repositorio
- Precarga modulos: preloadingStrategy: PreloadAllModules
- Comandos Angular CLI ng
- Material
- Angular material
- Angular Boostraphttps://www.digitalocean.com/community/tutorials/angular-viewchild-access-component-es
- The Most Powerful Angular UI Component Library
- Plugin Chrome para debug
- Angular Maps
- console
- AGM-Angular Google Maps: instalación
- AGM-Angular Google Maps: components
- Tutorial
- Curso Angular 8 EscuelaIT
- Ejemplo de Angular desplegado en node.js
- Code
- Ejemplo CRUD + Firebase
- Ejemplo Building a Real-Time Chat App with React and Firebase
- Es interesant per el tema del Firebase
- Repositori
- Migrar de una versión a otra
- AngularFire 2
- Auditoria:
- ng build --prod --stats-json
- Se graba stats-es2015.json en la carpeta dist
- npm install --save-dev webpack-bundle-analyzer
- npx webpack-bundle-analyzer dist/myapp/stats.json
- Angular genera 2 tipos de archivos. Para navegadores antiguos y actuales. Sólo carga los ficheros necesarios según tipo de navegador.
- Compilación:
- AOT: The Ahead-of-Time (AOT) compiler
- está definido en angular.json apartado configuration, production. Debe estar en yes
- ivy: Opting into Angular Ivy
- En angular 9 será obligatorio
- Se define en tconfig.json. Incluir en "enableIvy":true en angularCompileOptions
- nota: aot en angular.json debe estar a true
- Errores que me han pasado
- Actualización de proyectos de Angular 8 al 9
cd
carpeta_mi_proyecto_angular
ng update @angular/cli@8 @angular/core@8
ng update @angular/cli @angular/core
- Paquetes interesantes
- @schematics/update: ayuda a cambiar de versión de angular. Ya viene con angular.
- @schematics/update: ayuda a cambiar de versión de angular. Ya viene con angular.
- Ver fotos de google drive
- <img src='https://drive.google.com/uc?export=view&id=0VNJV2NyOUtWclltOXM' style="width: 50px; max-width: 100%; height: auto">
Instalación:
- sudo npm i -g @angular/cli
- ng -v
- ng new my-dream-app
- cd my-dream-app
- dentro de la carpeta podemos con ng -v podemos ver con más detalle la cl que tenemos de angular para el proyecto en particular.
- ng serve (por defecto puerto 4200)
- ng serve -port 4300 (para cambiar puerto)
- ng serve -o (para que lo abra en el navegador por defecto)
- sudo npm install --unsafe -perm -g @angular/cli (en el cas de que la Mac no vagi bé)
- Setup
- Incluir si ya no está /dist en .gitignore antes de subir el proyecto a GitHub para que no la suba después de ejecutar ng build --prod
Añadir componentes, módulos, servicios, etc
- ng generate component nombre-carpeta/nombre-componente
- ng g c nombre-carpeta/nombre-componente (forma abreviada)
- ng generate component nombre-carpeta/nombre-componente --dry-run (--dry-run nos mostrará lo que hace pero sin modificar ficheros. Sirve cuando no estamos seguros de lo que hará el comando ng.)
- ng g module appRouting --flat (--flat no nos crea la carpeta la carpeta app-routing y dentro el modulo approuting.module.ts)
- ng g m pages/post --routing. (crea el modulo y un archivo de configuración de rutas
- ng g c nombre-carpeta/nombre-componente --spec=false -is -it (no debug,no css propio, no template)
- ng g c nombre-carpeta/nombre-componente -is --skipTexts (no css propio, no archivo tests
- ng generate pipe nombre-carpeta/nombre-pipe
- ng g p nombre-carpeta/nombre-pipe (forma abreviada)
- ng g c nombre-carpeta/nombre-componente --module=app.module
- Cuando tengamos 2 módulos, hay que indicar en qué módulo hay que importar el componente. En este caso --module=app.module
- Ej:- creamos la carpeta components dentro de la carpeta app
- creamos la carpeta footer dentro de la carpeta components
- nos situamos en la carpeta principal que contiene todo el proyecto
- ng crea el componente footer en la carpeta -components/footer: entre otros ficheros: footer.component.(html,ts,css,etc...) - ng g guard services/auth --skipTests: genera src/app/services/auth.guard.ts
- Al crear un guard pide que elijamos entre:
- CanActivate (cuando no trabajamos con lazyload)
- CanActivateChild (si la ruta tiene rutas hijas)
- CanDeactivate ( de momento no lo sé ???????)
- CanLoad (cuando utilizamos lazyload)
- El unico que he elegido hasta ahora es CanActivate.
- ng help: Ayuda
- Si queremos ayuda más restringida tecleamos lo máximo que sabemos
- ng g c --help
- ng g m --help
- ng new --help
- ng new clitest --directory="ej1"
- ng serve --help
- ng serve --port 4201 -o
Actualizar versión angular:
- descargar ultima version NodeJS
- npm install -g npm@latest
- npm cache clean --force
- npm set audit false (????)
- npm uninstall -g angular-cli
- npm uninstall -g @angular/cli
- npm cache clean --force
- npm install -g @angular/cli@latest
Cuando hacemos "npm install "y al ejecutar "ng serve" nos dá muchos errores:
- Esto es debido a que por ejemplo en el package.json tenemos una versión anterior de angular a la que tenemos instalado en global
- ng update --all nos dá un informe de lo que pasa
- ng update --all --force actualiza todo lo que ha mostrado el informe del punto anterior
- Una vez corregido estos errores puede que al ejecutar de nuevo ng serve nos dé un error de typescript Error: The Angular Compiler requires TypeScript >=3.6.4 and <3.8.0 but 3.8.3 was found instead.
- Es necesario ejecutar npm i typescript@3.64 para el error del punto anterior
- En el apartado tree-shakeable se indica si la librería que queremos utilizar, solamente se cargan los paquetes que utilicemos
TypeScript
- ng add @angular/material
- The ng add command will additionally perform the following configurations:
Add project dependencies to package.json
Add the Roboto font to your index.html
Add the Material Design icon font to your index.html
Add a few global CSS styles to:
Remove margins from body
Set height: 100% on html and body
Set Roboto as the default application font
You're done! Angular Material is now configured to be used in your application. - Aclaración
- Si hemos decidido instalar hammer, añade import 'hammerjs en main.ts
- En app.module.ts se añade import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; o import { NoAnimationsModule } from '@angular/platform-browser/animations' y según lo que hayamos respondido en ng add "@angular/material y a continuación lo incluye en
- En angular.json se incluye en "styles" los módulos
- En index.htm se añaden los enlaces a los fonts de google de iconos y letras
- Getting Started
Instalar bootstrap en node-modules:
- parar el servidor ng serve
- npm install bootstrap --save
- npm install jquery --save
- npm install popper.js --save
- arrancar el servidor ng serve y si compila bien significa que todo ok
- Modificar el Archivo 'angular.json' para:
- "styles": [
- "src/styles.css",
- "node_modules/bootstrap/dist/css/bootstrap.min.css"
- ],
- "scripts": [
- "node_modules/jquery/dist/jquery.slim.min.js",
- "node_modules/popper.js/dist/umd/popper.min.js",
- "node_modules/bootstrap/dist/js/bootstrap.min.js"
- ]
Instalar ng-bootstrap: (requiere haber instalado bootstrap)
- npm install --save @ng-bootstrap/ng-bootstrap
- Utilización en un módulo
- Importar todo
- Importar lo que necesitas
- import {NgbModule} from '@ng-bootstrap/ng-bootstrap';
- @NgModule({
- ...
- imports: [NgbModule, ...],
- ...
- })
- export class YourAppModule { }
- import {NgbPaginationModule, NgbAlertModule} from '@ng-bootstrap/ng-bootstrap';
- @NgModule({
- ...
- imports: [NgbPaginationModule, NgbAlertModule, ...],
- ...
- })
- export class YourAppModule { }
Instalar Font Awesome en node-modules: font awesome
- parar el servidor ng serve
- npm install --save @fortawesome/fontawesome-free
- Modificar el Archiv 'angular.json' para: "styles": [
"src/styles.css",
"node_modules/bootstrap/dist/css/bootstrap.min.css",
"node_modules/@fortawesome/fontawesome-free/css/fontawesome.min.css"]
- angularfire
- Se requiere haber instalado @angular/cli
- npm install @angular/fire firebase --save
- Copiar las credenciales paras dk de Firebase en environtment.ts y environtment.prod.ts
- export const environment = {production: false,firebase: {apiKey: 'Axxxxxxxxxxxxxx',authDomain: 'firestore-xxxxxxxxxx',databaseURL: 'https://firestorexxxxxx',projectId: 'firestore-xxxxxxx',storageBucket: 'firestore-xxxxxxxxx',messagingSenderId: '111111111111',appId: '222222222222222',measurementId: 'A-AAAAAAA'}};
- Importar Firestore en xxx.module.ts código en xxx.module.ts
- import { BrowserModule } from '@angular/platform-browser';import { AngularFireModule } from '@angular/fire';import { AngularFirestoreModule } from '@angular/fire/firestore';import { environment } from '../environments/environment';.........import { AppComponent } from './app.component';........NgModule({declarations: [AppComponent],imports: [BrowserModule,.......,.......,HttpClientModule, AngularFireModule.initializeApp(environment.firebase),AngularFirestoreModule],providers: [GameService],bootstrap: [AppComponent]})export class AppModule { }
- Código ejemplo en componente
- import { Component, OnInit } from '@angular/core';import { AngularFirestore } from '@angular/fire/firestore';import { map } from 'rxjs/operators';import { Game } from '../../interfaces/interfaces';
@Component({selector: 'app-inicio',templateUrl: './inicio.component.html',styleUrls: ['./inicio.component.css']})export class InicioComponent implements OnInit {
juegos: any[] = [];constructor( private db: AngularFirestore ) { }
ngOnInit() {// obtener referencia a la db para detectar cambios en// la base de datos. "valueChanges()""// collection es un observable.// Necesitamos el pipe para que "resp" sea un array de// objetos con los atributos "name y value" que son los// que espera "grafico-barra.components.ts".// En "resp.map( ({ name, votos })...", utilizamos la// desustructuracion con ("{ name, votos })" en lugar de// (juegos)"
this.db.collection('goty').valueChanges().pipe(map( (resp: Game[]) => resp.map( ({ name, votos }) => ({ name, value: votos }) ))).subscribe( juegos => {// console.log('juegos',juegos);this.juegos = juegos;});
/* this.db.collection('goty').valueChanges().subscribe( resp => {// console.log(juegos);console.log("resp... ",resp);}); */
}
}
Ej.2 CRUD AngularFire
Ej.3 CRUD AngularFire
Ej.4 CRUD AngularFire
Ej.5 CRUD AngularFire
Acceso a developer twitter
Routing:
Caso1Caso 2
Caso3
Frequently Used Modules
NgModule
|
Import it from
|
Why you use it
|
@angular/platform-browser
|
When you want to run your app in a browser
| |
@angular/common
| ||
@angular/forms
| ||
@angular/forms
|
When you want to build reactive forms
| |
@angular/router
| ||
@angular/common/http
|
When you want to talk to a server
|
- Pipes
- Utiliza el patrón de funciones puras y memorized Si utilizamos el pipe en lugar de una función,al añadir un usuario, cuando se renderize de nuevo la lista con los usuarios, solo se calculará el pipe para el usuario añadido en lugar de calcular de nuevo para cada elemento de la lista. Forma parte de buenas prácticas
- Pipes-1: reverse, date-format, capitalizado, contraseña
- Pipes-2: domseguro
- Pipe map()
- How to Read the RxJS 6 Sources Part 1: Understanding of() and Subscriptions
- Reading the RxJS 6 Sources: Map and Pipe
- Pipes map()
- Pipes Angular
- DatePipe
- I18SelectPipe
- I18nPluralPipe
- SlicePipe
- KeyValuePipe
- JsonPipe
- AsyncPipe
- Como cambiar el idioma por defecto para ciertos pipes como moneda, fecha...
- En app.moduleimport localeEs from '@angular/common/locales/es';import localeFr from '@angular/common/locales/fr';import { registerLocaleData } from '@angular/common';registerLocaleData( localeEs );registerLocaleData( localeFr );......................providers: [{ provide: LOCALE_ID, useValue: 'es' }],
- The Most Powerful Angular UI Component Library
- Directivas: transformar el comportamiento del elemento html. *ngfor es una directiva que interna de Angular. Si sólo es para estilos, mejor utilizar CSS
- Servicios: Patrón inyección de dependencias.
- Singleton services
- http status code
- Si definimos providedIn: 'root' en el decorador, no es necesario importar el servicio en app.module.ts
- @Injectable({
providedIn: 'root'
}) - Sino ponemos providedIn: 'root' y el servicio lo queremos sólo para un módulo, lo importamos en el módulo y será una referencia única para ese módulo.
- Los componentes que lo necesitan lo inyectan en el constructor y lo llamamos en ngOnInit
- Crea una referencia única.
- En las directivas también se hace.
- Buena práctica
- @Injectable()export class DbzService {//definimos _personajes como privadaprivate _personajes: Personaje[] = [{nombre: 'Goku',poder: 15000},{nombre: 'Vegeta',poder: 7500}];// definimos un getter personajes publico querecupere _personajes y devuelva otro arrayDe esta manera, como en javascript los objetos sepasan por referencia, se devuelve otro array y nose puede modificar el array _personajes que es elque queremos privado.get personajes(): Personaje[] {return [...this._personajes];}constructor() {}agregarPersonaje( personaje: Personaje ) {this._personajes.push( personaje );}}
- RouterModule.forRoot( ROUTES, { useHash: true } )
- Añadimos el literal {useHash: true} esto añadirá un # a la ruta, que es un viejo truco de los navegadores para evitar que el navegador recargue la pagina. ????
- JSONPlaceholder
- Observables RxJS
- Eventos:
- (click): este evento se ejecuta cuando presionamos algo
- (onModelChange): cuando el valor de nuestra variable cambia. Requiere [(ngModel)]
- (focus): al interactuar con input y presionarlo para empezar a escribir este evento es lanzado
- (keydown): al presionar la tecla sobre cierto elemento
- (keyup): cuando soltamos la tecla este evento es ejecutado
- (dblclick): al dar doble click sobre un elemento
- (mouseenter): cuando movemos nuestro mouse sobre un elemento
- (mouseleave): al salir de ese elemento
@ViewChild decorator
debouncer time en un input:
- El tiempo de rebote es el retraso que podemos agregar entre las suscripciones a eventos. Como podemos agregar Debounce Time de 1000 milisegundos que se reinicia después de cada evento KeyUp por parte de un usuario, si el intervalo de tiempo entre el evento KeyUp excede los 1000 ms, entonces hacemos una suscripción o hacemos una llamada API.
- Ejemplo de un input: hecho manualmente. (En los formularios reactivos ya viene incorporado)
- import { Component, EventEmitter, Output, OnInit, Input } from '@angular/core';import { Subject } from 'rxjs';import { debounceTime } from 'rxjs/operators';@Component({selector: 'app-pais-input',templateUrl: './pais-input.component.html',styles: []})export class PaisInputComponent implements OnInit {@Output() onEnter : EventEmitter<string> = new EventEmitter();@Output() onDebounce: EventEmitter<string> = new EventEmitter();@Input() placeholder: string = '';debouncer: Subject<string> = new Subject();termino: string = '';ngOnInit() {this.debouncer.pipe(debounceTime(300)).subscribe( valor => {this.onDebounce.emit( valor );});}buscar() {this.onEnter.emit( this.termino );}teclaPresionada() {this.debouncer.next( this.termino );}}
interfaces a partir de json
- Copiar el json y pegarlo en la web de https://quicktype.io
- Seleccinar el lenguaje. En nuestro caso typescript
- A partir del resultado podemos crear un interface.ts para que Angular tenga el tipado
InfiniteScroll: @HostListener
- Utilizado en angular-cinema (home.component.ts)
Animate.css
Buenas prácticas
Pipes-1
Pipes-2
tslint.json
- En "max-line-length": [true, 140] podemos definir el máximo de caracteres por línea de código.
- En "max-line-length": [false, 140] podemos definir que no verifique el máximo de caracteres por línea de código.
Swiper: un buen slider. Utilizado en angular-cinema (home.component.ts)
ng-starrating - npm :
- crear la calificación promedio con estrellitas. Ejemplo en PeliculasApp (peliculas-poster-grid.component.ts)
Gráficos ngx-charts:
- Repositorio ngx-charts
- En la documentación/ejemplos tenemos el código StackBlitz
- Documentación
- npm install @swimlane/ngx-charts --save
- Ejemplo vertical bar char
- Código StackBlitz
- Copiar contenido de app.component.html de StackBlitz a el componente que estamos trabajando
- Copiamos el código de app.module.ts
- import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { NgxChartsModule } from '@swimlane/ngx-charts
- Y lo pegamos a nuestro módulo. A continuación importamos
- Copiar contenido de class AppComponent en app.component.ts de StackBlitz a el componente que estamos trabajando
- Copiar contenido de data.ts de StackBlitz a el componente que estamos trabajando
- Colores adobe para seleccionar colores de una misma gama
- ngx-charts (swimlane)