Diferencia entre revisiones de «Xulla Angular»
Ir a la navegación
Ir a la búsqueda
(→Pipes) |
|||
Línea 186: | Línea 186: | ||
<tr *ngFor="let product of productos | productFilter: filtre;"> | <tr *ngFor="let product of productos | productFilter: filtre;"> | ||
</syntaxhighlight> | |||
== Guards == | |||
ng g guard product/guards/product-detail | |||
<syntaxhighlight lang="javascript" style="font-family:monospace"> | |||
{ path: 'product/:id', | |||
canActivate: [ProductDetailGuard], | |||
component: ProductDetailComponent}, | |||
</syntaxhighlight> | |||
<syntaxhighlight lang="javascript" style="font-family:monospace"> | |||
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; } | |||
</syntaxhighlight> | |||
== Interceptors == | |||
<syntaxhighlight lang="javascript" style="font-family:monospace"> | |||
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, | |||
}], | |||
</syntaxhighlight> | </syntaxhighlight> |
Revisión actual - 11:36 23 feb 2022
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
- *ngIF
- *ngFor
- Plantilla:I Plantilla:Cita (index, first, last, even, odd)
- else ngSwitch i exemple de combinacions:
<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,
}],