História e evolução do Angular
- #Angular
- #JavaScript
O Angular, uma das tecnologias mais populares e poderosas para o desenvolvimento de aplicações web, e tem evoluído de maneira significativa desde seu lançamento, e para entender um pouco mais sobre ele, vamos entender um pouco mais do seu histórico e evolução durante o tempo.
O que é o Angular?
Angular é um framework de desenvolvimento web open-source mantido pela Google, criado para facilitar a construção de aplicações dinâmicas e robustas. Desde seu surgimento, o Angular tem sido amplamente adotado por desenvolvedores devido à sua eficiência, modularidade e suporte extensivo.
Surgimento do Angular — AngularJS (2010)
AngularJS, lançado em 2010, foi a primeira versão do framework. Criado por Misko Hevery e Adam Abrons, AngularJS trouxe um novo paradigma para o desenvolvimento web ao introduzir conceitos como two-way data binding, injeção de dependências e diretivas. Seu objetivo era simplificar o desenvolvimento e os testes de aplicativos web, promovendo uma abordagem mais modular e estruturada.
Principais Funcionalidades do AngularJS
- Two-way Data Binding: Sincronização automática entre o modelo e a visualização.
- Diretivas: Extensões HTML personalizadas que encapsulam funcionalidades.
- Injeção de Dependências: Gerenciamento automático de dependências, facilitando a modularidade e os testes.
- Roteamento: Navegação eficiente entre diferentes vistas.
Aplicabilidade
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<title>AngularJS Example</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script>
</head>
<body ng-controller="myController">
<h1>{{ message }}</h1>
<input type="text" ng-model="message">
<ul>
<li ng-repeat="item in items">{{ item }}</li>
</ul>
<script>
var app = angular.module('myApp', []);
app.controller('myController', function($scope) {
$scope.message = "Hello, AngularJS!";
$scope.items = ["Item 1", "Item 2", "Item 3"];
});
</script>
</body>
</html>
No código acima vemos a aplicabilidade de dois conceitos introduzidos no AngularJs como o Two-way Data Binding realizando a sincronização automática de campos e textos e as diretivas como o ng-model
e ng-controller
que oferecem um jeito de marcar o template e manipular seus valores via script, e o ng-repeat
, que permite gerenciar valores em loops no template.
Limitações do AngularJS
Apesar de suas inovações, o AngularJS enfrentou problemas de desempenho em grandes aplicações e uma curva de aprendizado acentuada devido à complexidade crescente conforme o projeto se expandia. A equipe da Google reconheceu essas limitações e começou a trabalhar em uma reescrita completa do framework.
Surgimento do Angular (Angular 2+) (sem Js)
Angular 2 (2016)
Em 2016, foi lançado o Angular 2, uma reescrita completa do AngularJS. Esta nova versão abandonou muitas das ideias e conceitos do AngularJS, adotando uma abordagem mais alinhada com as melhores práticas do desenvolvimento web atual.
Angular 2 introduziu o TypeScript como a linguagem padrão, melhorando a estruturação do código e a produtividade do desenvolvedor.
Principais Funcionalidades do Angular 2
- TypeScript: Superset do JavaScript que adiciona tipagem estática e outras funcionalidades avançadas.
- Componentes: Estrutura baseada em componentes, promovendo a reutilização e modularidade.
- RxJS: Programação reativa para lidar com eventos assíncronos.
- Roteamento Modular: Sistema de roteamento mais flexível e poderoso.
- Injeção de Dependências Aprimorada: Melhor gerenciamento de dependências e ciclo de vida de componentes.
Aplicabilidade
// app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule],
providers: [SomeService],
bootstrap: [AppComponent]
})
export class AppModule { }
// app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<h1>{{ title }}</h1>
<input [(ngModel)]="title">
<ul>
<li *ngFor="let item of items">{{ item }}</li>
</ul>
`,
styles: []
})
export class AppComponent {
title = 'Hello, Angular!';
items = ['Item 1', 'Item 2', 'Item 3'];
}j
Aqui já temos uma estruturação bem diferente do visto no AngulaJs, com a utilização do conceito de módulo e componente, o decorator @NgModule
define um objeto de metadata com as configurações do módulo em questão declarando componentes, diretivas e pipes, permitindo suas exportações para outros módulos ou importação destes de terceiros. Também permite a utilização de serviços por meio da declaração providers
.
Angular 4 (2017)
Visando maior praticidade no trabalho com animações, foi separado o módulo de animais do angular de seu nucleo, além de melhorias de performance.
- Animações Modulares: Separação do módulo de animações do núcleo do Angular.
- Melhorias de Performance: Redução do tamanho do pacote e aumento da velocidade de inicialização.
Aplicabilidade
// app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { AppComponent } from './app.component';
import { trigger, state, style, transition, animate } from '@angular/animations';
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, BrowserAnimationsModule],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
// app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<div [@simpleFadeAnimation]="isShown ? 'shown' : 'hidden'" class="animated-box">
Animated Box
</div>
<button (click)="toggle()">Toggle Animation</button>
`,
styles: [`
.animated-box {
width: 200px;
height: 200px;
background-color: #4CAF50;
margin: 20px;
text-align: center;
line-height: 200px;
color: white;
}
`],
animations: [
trigger('simpleFadeAnimation', [
state('hidden', style({
opacity: 0
})),
state('shown', style({
opacity: 1
})),
transition('hidden => shown', [
animate('0.5s')
]),
transition('shown => hidden', [
animate('0.5s')
])
])
]
})
export class AppComponent {
isShown = true;
toggle() {
this.isShown = !this.isShown;
}
}
Aqui criamos uma animação chamada simpleFadeAnimation acionada por um botão, que ao ser clicado, uma caixa desaparece e reaparece com uma animação de fade, utilizando a propriedade transition
do BrowserAnimationsModule.
Angular 5 (2017)
No Angular 5, o suporte para Progressive Web Apps (PWAs) foi adicionado, permitindo que as aplicações se comportem como aplicativos nativos em dispositivos móveis e desktop, com funcionalidades como instalação no dispositivo e suporte offline.
- Build Optimizer: Otimizações de compilação para melhorar o desempenho.
- Service Workers: Suporte nativo para Progressive Web Apps (PWAs).
Aplicabilidade
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { ServiceWorkerModule } from '@angular/service-worker';
import { environment } from '../environments/environment';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
ServiceWorkerModule.register('ngsw-worker.js', { enabled: environment.production })
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Na raiz do projeto era criado o arquivo ngsw-config.json no qual contia configurações para o Service Worker. Essa configuração permite que a aplicação seja instalada no dispositivo do usuário, funcione offline e ofereça uma experiência similar a de aplicativos nativos. Isso aumenta a acessibilidade e a usabilidade da aplicação, melhorando a experiência do usuário.
Angular 6 (2018)
O NgRx é uma biblioteca para Angular inspirada no Redux, que facilita a gestão de estado em aplicações Angular.
- Angular CLI Schematics: Ferramentas para automação de tarefas e geração de código.
- NgRx: Implementação oficial do padrão Redux para gerenciamento de estado.
Aplicabilidade
Para entender melhor a sua aplicabilidade veja esse artigo.
Angular 7 (2018)
- Drag and Drop: API nativa para arrastar e soltar.
- Virtual Scrolling: Renderização eficiente de listas grandes.
Aplicabilidade
// app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { DragDropModule } from '@angular/cdk/drag-drop';
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, DragDropModule],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
// app.component.ts
import { Component } from '@angular/core';
import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
@Component({
selector: 'app-root',
template: `
<h1>{{ title }}</h1>
<input [(ngModel)]="title">
<ul>
<li *ngFor="let item of items" cdkDrag>{{ item }}</li>
</ul>
`,
styles: []
})
export class AppComponent {
title = 'Hello, Angular 7!';
items = ['Item 1', 'Item 2', 'Item 3'];
}
No exemplo acima, temos a importação do DragDropModule e sua utilização nos elementos da lista de items pela declaração cdkDrag
, permitindo mover os itens nativamente.
Angular 8 (2019)
- Ivy Preview: Novo mecanismo de renderização mais rápido e eficiente.
- Diferenciação de Carga (Lazy Loading): Suporte aprimorado para carregamento diferido de módulos.
Aplicabilidade
// app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { RouterModule, Routes } from '@angular/router';
const routes: Routes = [
{
path: 'home',
loadChildren: () => import('./lazy/lazy.module').then(m => m.LazyModule)
}
];
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, RouterModule.forRoot(routes)],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
// lazy.module.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { LazyComponent } from './lazy.component';
@NgModule({
declarations: [LazyComponent],
imports: [CommonModule],
exports: [LazyComponent]
})
export class LazyModule { }
// lazy.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-lazy',
template: `
<h1>Lazy Loaded Component</h1>
`,
styles: []
})
export class LazyComponent { }
No AppModule realizamos o carregamento do LazyComponent somente ao ser acessado a rota “/home”, em outras rotas esse componente não será carregado, melhorando assim a performance da aplicação.
Angular 9 (2020)
- Ivy como Padrão: Ivy se torna o motor de renderização padrão, melhorando a performance e a capacidade de depuração.
- Depuração Melhorada: Mensagens de erro e advertências mais descritivas e informativas
- Ferramentas de Atualização: Melhorias na ferramenta de atualização, facilitando a migração entre versões do Angular usando o cli.
- FormGroup e FormControl: Melhor suporte e novos recursos para o gerenciamento de formulários.
Aplicabilidade
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
@Component({
selector: 'app-example-form',
templateUrl: './example-form.component.html',
styleUrls: ['./example-form.component.css']
})
export class ExampleFormComponent {
exampleForm: FormGroup;
constructor(private fb: FormBuilder) {
this.exampleForm = this.fb.group({
name: ['', Validators.required],
email: ['', [Validators.required, Validators.email]]
});
}
onSubmit() {
if (this.exampleForm.valid) {
console.log('Form Submitted', this.exampleForm.value);
}
}
}
O exampleForm é criado usado ofb.group
, no qual são definidos os seus campos (input
) , e as validações por formato de valor que recebem e se são campos obrigatórios.
<form [formGroup]="exampleForm" (ngSubmit)="onSubmit()">
<label for="name">Name</label>
<input id="name" formControlName="name">
<div *ngIf="exampleForm.get('name').invalid && exampleForm.get('name').touched">
Name is required
</div>
<label for="email">Email</label>
<input id="email" formControlName="email">
<div *ngIf="exampleForm.get('email').invalid && exampleForm.get('email').touched">
<div *ngIf="exampleForm.get('email').errors.required">Email is required</div>
<div *ngIf="exampleForm.get('email').errors.email">Email is invalid</div>
</div>
<button type="submit" [disabled]="exampleForm.invalid">Submit</button>
</form>
Aqui fazemos a ligação da estrutura criada no componente com o seu template, onde em ambos o formGroup
e formControlName
do template e dos valores definidos no construtor, devem ser correspondentes.
Angular 10 (2020)
- Warnings de Imports Desnecessários: Ferramentas para identificar e remover imports redundantes.
- Depuração Aprimorada: Melhor suporte para depuração e diagnósticos.
Angular 11 (2020)
- Hot Module Replacement (HMR): Atualização de módulos sem recarregar a página.
- Component Test Harnesses: Ferramentas para facilitar os testes unitários de componentes.
Angular 12 (2021)
- Suporte ao Webpack 5: Melhorias em build e performance.
- Nullish Coalescing: Nova sintaxe para simplificar a manipulação de valores nulos ou indefinidos.
Aplicabilidade
import { Component } from '@angular/core';
@Component({
selector: 'app-user-profile',
templateUrl: './user-profile.component.html',
styleUrls: ['./user-profile.component.css']
})
export class UserProfileComponent {
user = {
name: null,
age: undefined,
email: 'user@example.com'
};
// Utilizando Nullish Coalescing
userName: string = this.user.name ?? 'Default User';
userAge: number = this.user.age ?? 30;
userEmail: string = this.user.email ?? 'default@example.com';
}
Aqui definimos valores padrão para as variáveis, por exemplo o userName. Se tiver valor definido em this.user.name será atribuido esse valor ao userName, caso o contrário, o valor apresentado será “Default User”, e o mesmo acontece para userAge e userEmail.
Angular 13 (2021)
- Remoção de Suporte ao IE11: Simplificação do código base e adoção de funcionalidades modernas.
- Atualização de APIs: Melhorias nas APIs existentes e introdução de novas funcionalidades.
Angular 14 (2022)
- Standalone Components: Introdução de componentes standalone para maior flexibilidade.
- Typed Forms: Tipagem estática para formulários reativos.
Aplicabilidade
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-standalone-component',
standalone: true,
imports: [CommonModule],
template: `
<p>
Componente Standalone!
</p>
`,
styles: [`
p {
color: green;
}
`]
})
export class StandaloneComponent { }
Pela declaração standalone: true
em @Component
A temos a indicação que esse nâo é um componente “standard” padrão do Angular. A maior diferença dos componentes standalone é o fato de poderem serem utilizados em variadas partes da aplicação e não precisa ser declarado em um módulo.
Podemos utilizá-lo diretamente no template principal, como por exemplo, no src/app/app.component.html
, realizando a chamada abaixo.
//app.component.html
<app-standalone-component></app-standalone-component>
Angular 15 (2022)
- Modularidade Aprimorada: Melhorias na organização e modularização do código.
- Desenvolvimento de Bibliotecas: Ferramentas para criação e manutenção de bibliotecas Angular.
Aplicabilidade
{
...
"projects": {
"my-app": {
...
"architect": {
"build": {
"options": {
"assets": [
"projects/my-lib/src"
],
...
}
}
}
}
}
}
No arquivo angular.json pode ser incluida a url do projeto da biblioteca que deseja consumir no seu projeto atual em architect > build > options > assets.
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { MyLibModule } from 'my-awesome-lib';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
MyLibModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Depois o módulo da lib pode ser importado no módulo da sua aplicação e seus componentes utilizados.
Angular 16 (2023)
- Hidratação Parcial: Suporte para SSR (Server-Side Rendering) com hidratação parcial.
- Desempenho Aprimorado: Melhorias significativas de desempenho em tempo de execução.
Angular 17 (2024)
- Signals: Novo sistema reativo para otimização de desempenho e simplicidade.
- Incremental Builds: Compilação incremental para tempos de build mais rápidos.
- Estrutura Modular: Organização modular para facilitar o desenvolvimento em grande escala.
Aplicabilidade
import { Component, OnInit, Signal } from '@angular/core';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
counter = new Signal(0);
constructor() { }
ngOnInit(): void {
}
increment() {
this.counter.update(count => count + 1);
}
decrement() {
this.counter.update(count => count - 1);
}
}
A manipulação do valor de this.counter é controlada pela função update
, disponível nessa variável por ela ter sido declarada como um Signal
, obtendo um melhor gerenciamento dos estados reativos de forma mais eficiente.
Desde seu surgimento como AngularJS até a versão mais recente, Angular evoluiu significativamente, adaptando-se às necessidades dos desenvolvedores e às tendências do desenvolvimento web. Com suas novas funcionalidades, otimizações de desempenho e foco na modularidade, Angular é uma escolha comum para o desenvolvimento de aplicações web que planejam crescer e escalar futuramente.
____________________________________________
🔗 Vamos conversar?
Quer trocar uma ideia? Deixe seu comentário e vamos conversar !
Se você gostou desse conteúdo, não esqueça de me seguir para não perder as novas publicações sobre tecnologia, desenvolvimento de software e inteligência artificial.
Vamos nos conectar? Veja meu LinkedIn 🚀
____________________________________________