William Grasel PRO
Desenvolvedor Web, Google Developer Expert, Microsoft Most Valuable Professional, palestrante, consultor e coordenador do AngularSP.
import {
bootstrapApplication
} from '@angular/platform-browser';
@Component({
selector: 'hello-world',
standalone: true,
template: `Hello {{ world }}`
})
export class HelloWorld {
world = "World";
}
bootstrapApplication(HelloWorld);
Reactive Extensions Library for JavaScript
import { Component, signal, computed, effect } from '@angular/core';
@Component({
selector: 'planilha',
template: `
<table>
<tr>
<th>First</th>
<th>Last</th>
<th>Full Name</th>
</tr>
<tr>
<td>{{ firstName() }}</td>
<td>{{ lastName() }}</td>
<td>{{ fullName() }}</td>
</tr>
</table>`
})
export class Planilha {
firstName = signal("William");
lastName = signal("Grasel");
fullName = computed(() =>
this.firstName() + " " + this.lastName()
);
lastNameChange = effect(() => console.log(
"Last name changed: " + this.lastName()
));
}
import { HttpClient, HttpClientModule } from '@angular/common/http';
import { Component, inject } from '@angular/core';
import { User } from './user.interface';
import { toSignal } from '@angular/core/rxjs-interop';
@Component({
selector: 'app-root',
standalone: true,
imports: [
HttpClientModule,
],
template: `
@if( user(); as data ) {
<h1>{{ data.title }}</h1>
}
`,
})
export class App {
http = inject(HttpClient);
user$ = this.http.get<User>("/user");
user = toSignal(this.user$); // Signal<User | undefined>
}
import { Component } from '@angular/core';
import { toSignal } from '@angular/core/rxjs-interop';
import { interval } from 'rxjs';
@Component({
selector: 'app-root',
template: `{{ counter() }}`,
})
export class App {
counterObservable$ = interval(1000);
// Signal<number>
counter = toSignal(this.counterObservable$, {
initialValue: 0
});
}
import { Component, Signal, inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { FilterService } from './filter.service';
import { toObservable } from '@angular/core/rxjs-interop';
@Component({
selector: 'app-root',
template: `{{ results$ | async }}`,
})
export class App {
http = inject(HttpClient);
query = inject(FilterService).query; // Signal<string>
query$ = toObservable(this.query);
results$ = this.query$.pipe(
switchMap(query => this.http.get('/search?q=' + query ))
);
}
@Component({
signals: true,
selector: 'user-profile',
template: `
<p>Name: {{ firstName() }} {{ lastName() }}</p>
<p>Disabled: {{ disable() }}</p>
`,
})
export class UserProfile {
// readonly Signal<string|undefined>
firstName = input<string>();
// readonly Signal<string>
lastName = input('Smith');
// readonly Signal<string>
nickName = input.required<string>();
// EventEmitter<number>
saved = output<number>();
// Cria um modelo, um *writable* signal que suporta two-way binding.
disable = model(false); // WritableSignal<boolean>
}
@Component({
template: `
<div #el>element to query</div>
`
})
export class App {
// returns Signal<ElementRef<HTMLDivElement> | undefined>
divEl = viewChild<ElementRef<HTMLDivElement>>('el');
// returns Signal<ElementRef<HTMLDivElement>>
divElReq = viewChild.required<ElementRef<HTMLDivElement>>('el');
// returns Signal<readonly ElementRef<HTMLDivElement>[]>
divEls = viewChildren('el');
}
By William Grasel
Angular sempre foi um framework reativo, mas para muitos desenvolvedores o RxJS pode ser difícil de absorver e dominar, tornando uma solução demasiadamente complexa para problemas comuns do dia a dia. Signals vem para ser a nova primitiva reativa do framework, simples, prática e fácil, além de uma perfeita integração com RxJS que continua sendo importante para os casos reativos mais complexos! Vamos entender como os Signals funcionam, como eles se integram no ecossistema atual, o que você vai precisar aprender, e qual o futuro do framework com essa novidade!
Desenvolvedor Web, Google Developer Expert, Microsoft Most Valuable Professional, palestrante, consultor e coordenador do AngularSP.