Xulla Angular

De Jose Castillo Aliaga
Revisión del 11:36 23 feb 2022 de Admin (discusión | contribs.) (→‎Pipes)
(difs.) ← Revisión anterior | Revisión actual (difs.) | Revisión siguiente → (difs.)
Ir a la navegación Ir a la búsqueda

Instal·lar

sudo npm install -g @angular/cli [--force]
ng new my-app
cd my-app 
ng serve -o

CLI

  • Component: ng g component my-new-component
  • Directive: ng g directive my-new-directive
  • Pipe: ng g pipe my-new-pipe
  • Service: ng g service my-new-service
  • Class: ng g class my-new-class
  • Interface: ng g interface my-new-interface
  • Enum: ng g enum my-new-enum
  • Module: ng g module my-new-module
  • Guard: ng g guard my-new-guard
  • Afegir biblioteques: ng add @angular/material
  • Actualitzar: ng update --all
  • Compilar: ng build [--prod]
  • Crear projecte: ng new angular-projecte

Reactivitat

  • Interpolació normal: {{}}
  • Atributs: <img [src]="product.imageUrl" alt="">
  • Estils:
<td [ngStyle]="{'background-color': isEven?'red':'green'}">...</td>
<td [ngStyle]="{'width.px': width}">...</td> <!--width és una variable de TS-->
<td [ngStyle]="styleObject">...</td>  <!-- Variable de TS -->
<td [ngClass]="{'even': isEven, 'last': isLast}"></td>
<td [ngClass]="{'even': isEven, 'last active': isLast}"></td>
<td [ngClass]="classObject"></td> <!-- Variable de TS-->
 <p [ngStyle]="{'font-size': tamano+'px'}">Hola Mundo</p>
 <p [ngStyle]="{'font-size.px': tamano}">Hola Mundo</p>
 <p [style.fontSize.px]="tamano">Hola Mundo</p>
 <p [ngClass]="clase">Hola Mundo</p>
 <p [ngClass]="[clase, claseParrafo ]">Hola Mundo</p>
 <p [ngClass]="{'text-danger': danger, 'text-info': !danger}">Hola Mundo</p>
  • Bidireccional: [(ngModel)] <input type="text" [(ngModel)]="filterSearch" class="form-control" name="filterDesc" id="filterDesc" placeholder="Filter..."> (Cal importar FormModule en app.module.ts)
  • Esdeveniments: (click), (mouseenter),(keypress)... (click)="toggleImage()"

Directives

 <div *ngIf="show; else elseBlock">La condición es verdadera</div>
 <ng-template #elseBlock>La condición es falsa</ng-template>

     <span [ngSwitch]="property">
     <span *ngSwitchCase="'val1'">Value 1</span>
     <span *ngSwitchCase="'val2'">Value 2</span>
     <span *ngSwitchCase="'val3'">Value 3</span>
     <span *ngSwitchDefault>Other value</span>
     </span>

  <ng-container *ngFor="let person of persons"> <!-- Desaparece -->
    <ng-container *ngIf="person.age >= 18"> <!-- Desaparece -->
       <p>{{person | json}}</p> <!-- Sólo quedará este elemento -->
    </ng-container>
  </ng-container>

Components

  • @Input: @Input() products?: IProduct[]
<app-product-item [p]="product"
   *ngFor="let product of products">
   </app-product-item> </div>
  • @Output: @Output() rattingChanged = new EventEmitter<number>(); this.rattingChanged.emit(this.auxRatting); (rattingChanged)="changeRatting($event, product)"
  • Attibute selector: selector: '[app-edifici]', Utilitzar com atribut de l'etiqueta (útil per als tr)

Rutes

Fitxer: app-routing.module.ts

Etiqueta: <router-outlet>

Rutes amb #: imports: [RouterModule.forRoot(routes, { useHash: true })],

Exemple:

const routes: Routes = [
   {path: 'home', component: HomeComponent},
   {path: 'planets', canActivate: [AuthGuard], component: PlanetListComponent},
   {path: 'suns', canActivate: [AuthGuard], component: SunComponent},
   {path: 'planet/:id', canActivate: [AuthGuard], component: PlanetDetailComponent},
   {path: 'planet/edit/:id', canActivate: [AuthGuard],
   resolve: {planet: PlanetResolveService},
   component: PlanetEditComponent},
 
   {path: 'login', component: LoginComponent},
   {path: '**', pathMatch: 'full', redirectTo: 'home'}
 ];

Cridar a les rutes: <a class="nav-link active" aria-current="page" [routerLink]="['home']" [routerLinkActive]="['active']">Home</a>

Cridar a les rutes per codi:

import { Router } from '@angular/router';
constructor( private router: Router ) {}
detailsProduct(id: number): void{   this.router.navigate(['/product', id]); }


Servicis HTTP

En app.module.ts, en imports: HttpClientModule i importat de: import { HttpClientModule } from '@angular/common/http';

Exemple bàsic:

constructor(private http: HttpClient) { }
getProducts(): Observable<Product[]>{
   return this.http.get<{products: Product[]}>(this.productURL).pipe(
     map(response => response.products)
     );
 }

Exemple de POST:

import { HttpClient, HttpHeaders } from '@angular/common/http';

 private httpOptions = {
    headers: new HttpHeaders({
      'Content-Type':  'application/json',
    })
  };

this.http.post<{first: string, last: string}>(this.loginURL,JSON.stringify(datos),httpOptions) ...

Exemple de subscripció completa:

products: Product[] = [];
 ngOnInit(): void {
   this.productsService.getProducts().subscribe(
     prods => this.products = prods, // Success function
     error => console.error(error), // Error function (optional)
     () => console.log('Products loaded') // Finally function (optional)
     );
 }

Pipes

<tr *ngFor="let product of products">
     <td>
     <img [src]="product.imageUrl" 
      *ngIf="showImage" alt=""
     [title]="product.desc | uppercase">
     </td>
     <td>{{ product.description }}</td>
     <td>{{ product.price | currency:'EUR':'symbol'}}</td>
     <td>{{ product.available | date:'dd/MM/y' }}</td>
</tr>

Exemple pipe personalitzada

import { Pipe, PipeTransform } from '@angular/core';
import { Product } from '../product/product';
@Pipe({
 name: 'productFilter'
})
export class ProductFilterPipe implements PipeTransform { //al implementar PipeTransform cal fer la funció Transform
 transform(products: Product[], filterBy: string): Product[] { // el primer argument és el que cal filtrar i després una llista d'arguments
 // en aquest cas sols és un, el criteri de búsqueda
   const filter = filterBy ? filterBy.toLocaleLowerCase() : null; // passem el filtre a minúscules o a null si no està
   return filter ?  // Si no és null filtra
   products.filter(p => p.name.toLocaleLowerCase().includes(filter))
   : products; // si és null trau l'array sense filtre
 }}

<tr *ngFor="let product of productos | productFilter: filtre;">

Guards

ng g guard product/guards/product-detail
{ path: 'product/:id',
canActivate: [ProductDetailGuard],
component: ProductDetailComponent},


canActivate(
   route: ActivatedRouteSnapshot,  
   state: RouterStateSnapshot):
   Observable<boolean | UrlTree>
   | Promise<boolean| UrlTree>
   | boolean
   | UrlTree {
     const id = route.params.id; 
     if(isNaN(id) || id < 1){
       console.log('La id no funciona')
       return this.router.parseUrl('/cataloge'); 
     }
     return true; }


Interceptors

import { Injectable } from '@angular/core';
import { HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable({ providedIn: 'root'})
export class AuthInterceptorService {
 intercept(req: HttpRequest<any>, next: HttpHandler):Observable<HttpEvent<any>> {
   const token = localStorage.getItem('idToken'); // Token de locastorage
   if (token) {
   // Clonem la petició i afegiem el sufix
      const authReq = req.clone({url: req.url.concat(`?auth=${token}`)});
   // Enviem la petició en token
   return next.handle(authReq);   }
   return next.handle(req); 
// Sense tokens enviem la petició original
 }}

...

providers: [
   {
   provide: HTTP_INTERCEPTORS,
   useClass: AuthInterceptorService,
   multi: true,
   }],