Angular

Angular Detalhes

Conteúdo do curso

  1. Introdução

  2. Componentes

  3. Estrutura do projeto

  4. Angular CLI

  5. Módulos

  6. Data Binding

  1. Diretivas Estruturais

  2. Diretivas de Atributos

  3. Services

  4. Pipes

  5. Template-Driven Forms

Conteúdo do curso

  1. Reactive Forms

  2. Validações

  3. Ciclo de vida

  4. Rotas

  5. Guards

  6. Lazy Loading

  1. Requisições HTTP

  2. Interceptors

  3. Diretivas customizadas

  4. Injeção de dependência

  5. Segurança

Arquitetura

architecture angular application

Angular CLI

npm install -g @angular/cli
ng version
ng help
ng generate --help
ng new primeiro-projeto
cd primeiro-projeto
ng serve
ng generate module pessoa --routing
ng generate componente pessoa/cadastro

Data Binding

databinding

Data Binding - Exemplos

<li>{{itens[0]}}</li>
<li [innerHtml]="itens[0]"></li>
<a (click)="adicionar('Item')">Adicionar item a ser feito</a>
<input [(ngModel)]="movie.name">

Diretivas

Componentes são uma extensão de uma diretiva, com a adição de templates.

Existem dois tipos de diretivas:

  • Estruturais

  • Atributos

Diretivas estruturais

Alteram o Layout adicionando, removendo ou substituindo elementos da árvore de elementos do HTML (DOM).

  • ngIf: Exibe o elemento somente se a condição for verdadeira

  • ngFor: Adiciona um elemento para cada item da lista

Diretivas de atributo

Altera a aparência ou adiciona um comportamento a um elemento.

  • ngStyle

  • ngClass

  • ngModel

<input [(ngModel)]="movie.name">

Services

São valores, funções ou funcionalidades que uma aplicação precisa. São criados usando o decorator @Injectable().

@Injectable() class Car {

}

Services - Uso

@Injectable({ providedIn: 'root' })
class Car {
  constructor(@Inject("MyEngine") public engine:Engine) {}
}
@NgModule({
  // ...
  providers: [ ItemService ],
  // ...
})

Pipes

Facilidade para transformar valores nos templates.

import { Pipe, PipeTransform } from '@angular/core';
@Pipe({name: 'exponentialStrength'})
export class ExponentialStrengthPipe implements PipeTransform {                                transform(value: number, exponent: string): number {
    let exp = parseFloat(exponent);
    return Math.pow(value, isNaN(exp) ? 1 : exp);
  }
}

Pipes

  1. AsyncPipe

  2. CurrencyPipe

  3. DatePipe

  4. DecimalPipe

  5. UpperCasePipe

  6. TitleCasePipe

  1. LowerCasePipe

  2. JsonPipe

  3. I18nPluralPipe

  4. KeyValuePipe

  5. PercentPipe

  6. SlicePipe

Pipes - Uso

import { Component } from '@angular/core';
@Component({
  selector: 'app-hero-birthday',
  template: `<p>The hero's birthday is {{ birthday | date }}</p>` })
export class HeroBirthdayComponent {
  birthday = new Date(1988, 3, 15); // April 15, 1988
}
@NgModule({
  // ...
  declarations: [
    // ...
    HeroBirthdayComponent
  ],
  // ...
})

Template-driven Forms

import { FormsModule } from '@angular/forms';
@NgModule({
  imports:      [ BrowserModule, FormsModule ],
  // ...
})
export class AppModule { }
<input type="text" [(ngModel)]="item.nome" />

Template-driven Forms - Validação

<input type="text" [(ngModel)]="item.nome" required="true" #itemAdicionar="ngModel"/>

Template-driven Forms - Validação

Classes especiais de controle de validação:

StateVerdadeiroFalso

Visitado

ng-touched

ng-untouched

Modificado

ng-dirty

ng-pristine

Válido

ng-valid

ng-invalid

Template-driven Forms - Validação

Atributos da template reference variable do ngModel:

StateVerdadeiroFalso

Visitado

touched

untouched

Modificado

dirty

pristine

Válido

valid

invalid

Template-driven Forms - Validação

<form (ngSubmit)="adicionar()" #itemForm="ngForm">
    <input name="nome" type="text" [(ngModel)]="item.nome" required />
</form>

Components - Class field decorators

@Input()  botao: string;
@Output() itens = new EventEmitter<Item[]>();
@ViewChild(ItemListComponent) itemList: ItemListComponent;

Reactive Forms

import { ReactiveFormsModule } from '@angular/forms';
@NgModule({
  imports:[
    // ...
    ReactiveFormsModule
  ],
  // ...
})
export class AppModule { }
  itemForm: FormGroup = new FormGroup({
    nome: new FormControl(''),
    realizado: new FormControl(false),
  });
<form (ngSubmit)="adicionar()" [formGroup]="itemForm">
  <input type="text" formControlName="nome" />
  <input type="checkbox" formControlName="realizado" />
</form>

Reactive Forms - patchValues e setValue

this.itemForm.get('nome').patchValue('');
this.itemForm.patchValue(new Item());

Reactive Forms - FormBuilder

this.itemForm = this.fb.group({
  nome: [''],
  realizado: [false],
});

Reactive Forms - Validação

<input type="text" formControlName="nome" required />
<input formControlName="realizado" type="checkbox" />
this.itemForm = this.fb.group({
  nome: ['', Validators.required],
  realizado: [false],
});

Reactive Forms - FormArray

import { FormArray } from '@angular/forms';
//...
profileForm = this.fb.group({
  aliases: this.fb.array([
    this.fb.control('')
  ])
});
//...
get aliases() {
  return this.profileForm.get('aliases') as FormArray;
}
//...
addAlias() {
  this.aliases.push(this.fb.control(''));
}
//...

Reactive Forms - FormArray

<div formArrayName="aliases">
  <h3>Aliases</h3> <button (click)="addAlias()">Add Alias</button>
  <div *ngFor="let address of aliases.controls; let i=index">
    <label>Alias: <input type="text" [formControlName]="i"></label>
  </div>
</div>

Reactive Forms - ValidatorFn

export function forbiddenNameValidator(nameRe: RegExp): ValidatorFn {
  return (control: AbstractControl): {[key: string]: any} | null => {
    const forbidden = nameRe.test(control.value);
    return forbidden ? {'forbiddenName': {value: control.value}} : null;
  };
}
this.heroForm = new FormGroup({
  'name': new FormControl(this.hero.name, [
    Validators.required,
    Validators.minLength(4),
    forbiddenNameValidator(/bob/i)
  ])
])

Ciclo de vida

  1. ngOnChanges

  2. ngOnInit

  3. ngDoCheck

  4. ngAfterContentInit

  1. ngAfterContentChecked

  2. ngAfterViewInit

  3. ngAfterViewChecked

  4. ngOnDestroy

Feature Modules

São módulos que tem o propósito de organizar o código na aplicação. Ele é um conjunto de funcionalidades coesas e focados em necessidades específicas da aplicação.

@NgModule({
  imports: [
    CommonModule
  ],
  declarations: [
    CustomerDashboardComponent
  ],
  exports: [
    CustomerDashboardComponent
  ]
})

Route

@NgModule({
  imports: [
    RouterModule.forRoot(
      [
        { path: '',   redirectTo: '/heroes', pathMatch: 'full' },
        { path: '**', component: PageNotFoundComponent }
      ]
    )
  ]
})

Route - Router

import { Router } from '@angular/router';
// ...
constructor(private router: Router
// ...
this.router.navigate(['/item/list']);

Route - ActivatedRoute

import { ActivatedRoute } from '@angular/router';
// ...
constructor(private route: ActivatedRoute
// ...
this.router.navigate(['/item/list']);

Route - Guards

Um Route Guard é geralmente usado para impedir o acesso a determinadas rotas do sistema. Ele pode retornar os seguintes valores:

  • true: a navegação continua.

  • false: a navegação é interrompida e o usuário continua na rota atual.

  • UrlTree: o usuário é redirecionado para a rota de retorno.

  • any: Com o resolver guard.

Route - Guards

  • CanActivate: para mediar navegações para uma rota.

  • CanActivateChild: para mediar navegações para uma rota filha.

  • CanDeactivate: para mediar navegações de saída da rota atual.

Route - Guards

  • Resolve: para realizar recuperação de dados antes da ativação da rota atual.

  • CanLoad: para mediar a navegação para um feature module carregado de forma assíncrona.

Lazy Loading

  • Eager Loading: Por padrão os módulos são carregados junto com a aplicação, sendo eles necessários ou não.

  • Lazy Loading: Padrão utilizado para carregamento tardio do recurso. O módulo é carregado quando necessário.

HttpClient

import { HttpClientModule } from '@angular/common/http';
// ...
@NgModule({
  imports: [
    HttpClientModule,
// ...
})
// ...
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable()
export class ConfigService {
  constructor(private http: HttpClient) { }
}

HttpClient - Interceptor

import { Injectable } from '@angular/core';
import {
  HttpEvent, HttpInterceptor, HttpHandler, HttpRequest
} from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable()
export class NoopInterceptor implements HttpInterceptor {

  intercept(req: HttpRequest<any>, next: HttpHandler):
    Observable<HttpEvent<any>> {
    return next.handle(req);
  }
}
{ provide: HTTP_INTERCEPTORS, useClass: NoopInterceptor, multi: true },

Diretivas - Atributos

<p [item]="item"></p>
import { Directive, ElementRef, Input } from '@angular/core';
//...

@Directive({
  selector: '[item]'
})
export class HighlightDirective {

  @Input('item') item: Item;

  constructor(el: ElementRef) {
    // ..
    el.nativeElement.style.backgroundColor = 'yellow';
  }
}

Diretivas - Estrutural

<div *itensMostrar="itens">{{item.name}}</div>

<ng-template [itensMostrar]="itens">
  <div>{{item.name}}</div>
</ng-template>
import { Directive, Input, TemplateRef, ViewContainerRef} from '@angular/core';
//...

@Directive({ selector: '[itensMostrar]'})
export class ItensMostrarDirective {
  constructor(
    private templateRef: TemplateRef<any>,
    private viewContainer: ViewContainerRef) { }
//...
}

Injeção de dependência

O angular possue um injetor de dependência hierárquico, ou seja existe uma arvore de injetores de dependência que fica em paralelo a arvore de componentes da aplicação. Ele pode ser reconfigurado em qualquer nível da arvore de dependência do angular.

Injeção de dependência: Scope

Os services podem possuir escopo limitado a módulos do sistema. Quando declarados em módulos o escopo do módulos pode ser definido no providedIn do próprio componente ou dentro da declaração de provides dos módulos.

@Injectable({
  providedIn: UserModule,
})
export class UserService {}
@NgModule({
  providers: [UserService],
})
export class UserModule {}

Injeção de dependência: Scope

Quando o escopo é limitado a um componente ele é disponível a toda arvore daquele componente.

@Component({
  providers: [UserService]
})
export class UserComponent {}

Injeção de dependência: Singleton Services

Singleton services são serviços que possuem somente uma instância em todo a aplicação. São implementados sendo declarados no AppModule ou com providedIn igual a "root".

Segurança

  • XSS: Cross-site scripting

  • CSRF or XSRF: Cross-site request forgery

  • XSSI: Cross-site script inclusion

Referências

Dúvidas

Alguma pergunta?