Angular signallar


Signallar reaktiv state (holat): chaqirish orqali o‘qing (masalan, count() ), set() / update() bilan yangilang, computed() bilan oling va effect() bilan yon ta’sirlarni ishga tushiring.


ULASHISH

Signallar uchun asoslar

  • Signal: Siz uni chaqirish orqali o‘qigan qiymat (masalan, count()). Uni yangilash qaramog‘idagilarni xabardor qiladi.
  • Holat: Mahalliy component holati uchun signal() dan foydalaning.
  • Olingan: faqat o‘qish uchun formulalar uchun computed() dan foydalaning.
  • Effektlar: Bog‘liqlar o‘zgarganda nojo‘ya effektlarni ishga tushirish uchun effect() dan foydalaning.
import { signal, computed, effect } from '@angular/core';

const count = signal(0);
const double = computed(() => count() * 2);
effect(() => console.log('count =', count()));

count.update(n => n + 1);

Eslatmalar:

  • Aloqador: Ma’lumotlarni ulash, xizmatlar va DI va o‘zgarishlarni aniqlash bo‘limlariga qarang.
  • Mahalliy component holati uchun signallardan foydalaning.
  • RxJS-ni kerak bo‘lganda toSignal()/toObservable() bilan ko‘prik.
  • Eski ekvivalentlik: ro‘yxatlar uchun trek bilan @for ni tanlang; *ngFor bilan bir xil effekt uchun trackBy dan foydalaning.

Signallar bilan ishlash

Signalni .set() yoki .update() yordamida yangilang.

Signalni funksiya kabi chaqirish orqali o‘qing.

const count = signal(0);
count.set(1);
count.update(n => n + 1);
console.log(count());

Misol

Signaldan foydalaning, computed() bilan hosil qiling, effect() bilan reaksiyaga kirishing va update() bilan yangilang:

Misol

import { bootstrapApplication } from '@angular/platform-browser';
import { Component, signal, computed, effect } from '@angular/core';

@Component({
  selector: 'app-root',
  standalone: true,
  template: `
    <h3>Signals</h3>
    <p>Count: {{ count() }}</p>
    <p>Double: {{ double() }}</p>
    <button (click)="inc()">Increment</button>
  `
})
export class App {
  count = signal(0);
  double = computed(() => this.count() * 2);
  constructor() {
    effect(() => console.log('count changed', this.count()));
  }
  inc() { this.count.update(n => n + 1); }
}

bootstrapApplication(App);
<app-root></app-root>

Misolni ishga tushirish »

Misol tushuntirildi

  • signal(0): Siz chaqirish orqali o‘qigan reaktiv holatni yaratadi (masalan, count()).
  • computed(() => ...): Boshqa signallardan faqat o‘qish uchun qiymat (double()) chiqaradi.
  • effect(() => ...): Har safar bog‘liqliklar o‘zgarganda ishlaydi (count() yangilanishlarida jurnallar).
  • update(n => n + 1) : Signalga yozadi va qaramog‘idagilarni xabardor qiladi.

Maslahatlar:

  • O‘zgarmas: Mutatsiya o‘rniga set / update da yangi obyektlar/massivlar yaratishdan foydalaning.
  • Effektlarni kichikroq tuting: Teskari aloqa uzilishlarini oldini olish uchun effect() ichidagi signallarga yozishdan saqlaning.
  • Arzon hisoblang: computed() ni sof va arzon tuting; faqat boshqa signallardan kelib chiqadi.


Olingan qiymatlar va effektlar

  • computed() ichida faqat o‘qish uchun formulalarni o‘rash; u qaramliklar o‘zgarganda qayta hisoblaydi.
  • Ro‘yxatga olish yoki sinxronlash kabi nojo‘ya ta’sirlar uchun effect() dan foydalaning.
  • Effektlarni idempotent va yengil saqlang.
const a = signal(2);
const b = signal(3);
const sum = computed(() => a() + b());
effect(() => console.log('sum =', sum()));

Misol

computed() yordamida olingan qiymatni hisoblang va uni effect() yordamida kuzating:

Misol

import { bootstrapApplication } from '@angular/platform-browser';
import { Component, signal, computed, effect } from '@angular/core';

@Component({
  selector: 'app-root',
  standalone: true,
  template: `
    <h3>Derived & Effects</h3>
    <p>a: {{ a() }} | b: {{ b() }} | sum: {{ sum() }}</p>
    <button (click)="incA()">inc a</button>
    <button (click)="incB()">inc b</button>
  `
})
export class App {
  a = signal(2);
  b = signal(3);
  sum = computed(() => this.a() + this.b());
  constructor() { effect(() => console.log('sum =', this.sum())); }
  incA() { this.a.update(n => n + 1); }
  incB() { this.b.update(n => n + 1); }
}

bootstrapApplication(App);
<app-root></app-root>

Misol tushuntirildi

  • computed : a() yoki b() o‘zgarganda sum() qayta hisoblab chiqadi.
  • effect : sum() yangilanishlariga munosabat bildiradi (har bir o‘zgarishda qayd qilinadi).
  • incA()/incB(): signallarni oshirish uchun update’dan foydalaning — bu qayta hisoblashni ishga tushiradi.

Eslatmalar:

  • Hisoblangan nojo‘ya ta’sirlardan saqlaning: computed() ni toza tuting (async/mutatsiyalar yo‘q).
  • Hayot sikllari effekti: effect() ichini tozalang va har bir yugurishda keraksiz ishlardan qoching.
  • Interop: oqimlarni integratsiyalashganda toSignal()/toObservable() yordamida RxJS bilan ko‘prik.

RxJS bilan o‘zaro ishlash

  • Shablonga mos o‘qish uchun Observable ni toSignal() bilan signalga aylantiring.
  • Oqim API-lari bilan integratsiya qilish uchun signalni to Observable() yordamida Observablega aylantiring.
import { signal, computed, effect, toSignal, toObservable } from '@angular/core';
import { interval, map } from 'rxjs';

// Observable -> Signal
const seconds$ = interval(1000).pipe(map(n => n + 1));
const seconds = toSignal(seconds$, { initialValue: 0 });

// Signal -> Observable
const count = signal(0);
const count$ = toObservable(count);

Eslatmalar:

  • Boshlang‘ich qiymatlar: SSR va birinchi render uchun toSignal() ga har doim initialValue ko‘rsating.
  • Egalik: obunalarni kuzatish mumkin bo‘lgan tomondan boshqaring; toSignal() avtomatik ravishda yirtib tashlashni boshqaradi.

Signallarning tezkor ma’lumotnomasi

  • Create: signal(initial)
  • O‘qing: signalni chaqiring (masalan, count())
  • Write: set(value), update(fn)
  • Derived: computed(fn)
  • Effects: effect(fn)
  • RxJS interop: toSignal(observable, { initialValue }), toObservable(signal)


W3Schools Pathfinder

Yutuqlaringizni kuzating – bu bepul!