Czy wiesz, że w Angular 16 pojawią się sygnały?
Sygnały to nowa koncepcja w Angular, upraszcza ona tworzenie reaktywnych komponentów. Mogą one w przyszłości doprowadzić do usunięcia Zone.js z Angular.
Przykład utworzenia i odczytywania wartości z sygnału:
// tworzenie sygnału
name = signal('Szczupły Zbyszek');
// odczytywanie wartości
name();
// ustawienie nowej wartości
name.set('Piękna Marysia');
Do utworzenia sygnału potrzebna jest zawsze początkowa wartość. Obecną wartość z sygnału można odczytać wywołując sygnał jak funkcję. Przykład prostego komponentu:
@Component({
selector: 'simple-name-signal',
standalone: true,
imports: [CommonModule],
template: `
<p>{{ name() }}</p>
<button (click)="generateName()">Generate name</button>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class SimpleNameSignalComponent {
name = signal('Szczupły Zbyszek');
constructor(private generatorSerivce: GeneratorService) {}
generateName() {
this.name.set(this.generatorSerivce.generateName());
}
}
Jeżeli wartość sygnału name
nie ulegnie zmianie, komponent nie zostanie ponownie wyrysowany.
Sygnał zawsze posiada wartość, dlatego możliwe jest odczytanie ostatniej wartości np. w logice obsługi eventów:
@Component({
selector: 'simple-name-signal',
standalone: true,
imports: [CommonModule],
template: `
<p>{{ data() }}</p>
<button (click)="doSomething()">Do something</button>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class SimpleNameSignalComponent {
data = signal('Szczupły Zbyszek');
doSomething() {
console.log(this.data()); // wywołanie this.data(), zwróci ostatnią wartość, bez rekalkulacji!
}
}
Sygnały oferują możliwość agregowania, tak jak combineLatest z rxjs. Przykład:
// rxjs
name = new BehaviorSubject('gorgeous Zbyszek');
counter = new BehaviorSubject(0);
concat$ = combineLatest([this.name, this.counter]).pipe(
tap((data) => {
console.log('RXJS computing concat', data);
}),
map(([name, counter]) => `${name}, counter: ${counter}`)
);
this.name.next('Grześ');
this.name.next('Grześ');
// output
// RXJS computing concat ["Grześ", 0]
// RXJS computing concat ["Grześ", 0]
// signal
name = signal('gorgeous Zbyszek');
counter = signal(0);
concat = computed(() => {
console.log('SIGNAL computing concat');
return `${this.name()}, counter: ${this.counter()}`;
});
this.name.set('Grześ');
this.name.set('Grześ');
// output:
// SIGNAL computing concat
Sygnały działają jak producer-consumer. Jeżeli ustawiamy nową wartość na sygnale, konsumer - name()
otrzyma powiadomienie o zmianie i funkcja concat
zostanie przeliczona.
W przypadku rxjs zostaną wyemitowane dwa eventy. Wykorzystując dodatkowy operator - distinctUntilChanged
, wynik byłby taki sam jak w przypadku sygnałów.
A jak to wpłynie na NgRx? Nadal toczy się dyskusja (link, link). Proponowana jest możliwość stworzenia SignalStore oraz pobierania selektorów, które zwrócą sygnał:
data = this.store.selectSignal(selectData);
Przydatne linki
-
SENIOR FULLSTACK DEVELOPER (JAVA + ANGULAR) Poznań (hybrydowo) lub zdalnie UoP 14 900 - 20 590 PLN brutto
B2B 19 680 - 27 220 PLN netto -
REGULAR FULLSTACK DEVELOPER (JAVA + ANGULAR) Poznań (hybrydowo) lub zdalnie UoP 11 300 - 15 900 PLN brutto
B2B 14 950 - 21 000 PLN netto -
ZOBACZ WSZYSTKIE OGŁOSZENIA
newsletter
techniczny
Podobne wpisy
Czy wiesz, że w Angular 17 została wprowadzona alternatywa dla *ngFor?
-
SENIOR FULLSTACK DEVELOPER (JAVA + ANGULAR) Poznań (hybrydowo) lub zdalnie UoP 14 900 - 20 590 PLN brutto
B2B 19 680 - 27 220 PLN netto -
REGULAR FULLSTACK DEVELOPER (JAVA + ANGULAR) Poznań (hybrydowo) lub zdalnie UoP 11 300 - 15 900 PLN brutto
B2B 14 950 - 21 000 PLN netto -
ZOBACZ WSZYSTKIE OGŁOSZENIA