Rumah > hujung hadapan web > tutorial js > Peningkatan seterusnya dalam kereaktifan sudut

Peningkatan seterusnya dalam kereaktifan sudut

Mary-Kate Olsen
Lepaskan: 2024-11-17 22:19:01
asal
268 orang telah melayarinya

The next improvement in Angular reactivity

pengenalan

Sejak versi terbaru Angular, sistem kereaktifan primitif baharu telah dibangunkan dalam rangka kerja: isyarat!

Hari ini, dengan melihat ke belakang, kami menyedari bahawa kes penggunaan tertentu tidak dilindungi, dan jelas sekali pasukan Angular yang sangat reaktif akan memberikan kami pembantu untuk menampung kes penggunaan ini.

Apakah kes kegunaan ini? Apakah penyelesaian yang akan dilaksanakan dan bagaimanakah ia akan digunakan?

Proses menetapkan semula satu isyarat berbanding isyarat yang lain

Mari kita mulakan dengan menggambarkan masalah ini.

Bayangkan kita ada sebakul buah dengan kuantiti tertentu.
Kuantiti diuruskan oleh komponen, yang memasukkan buah.

@Component({
  template: `<button type="button" (click)="updateQuantity()"> 
    {{quantity()}}
    </button>`
})
export class QuantityComponent() {
  fruit = input.required<string>();
  count = signal(1);

  updateQuantity(): void {
    this.count.update(prevCount => prevCount++);
  }
}
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Di sini pembolehubah mesti ditetapkan semula jika buah harga input berubah.

Penyelesaian mudah ialah menggunakan kesan

@Component({
  template: `<button type="button" (click)="updateQuantity()"> 
    {{quantity()}}
    </button>`
})
export class QuantityComponent() {
  fruit = input.required<string>();
  quantity = signal(1);

  countEffect(() => {
    this.fruit();
    this.quantity.set(1);
  }, { allowSignalWrites: true })

  updateQuantity(): void {
    this.quantity.update(prevCount => prevCount++);
  }
}
Salin selepas log masuk
Salin selepas log masuk

Kod sebelumnya adalah amalan buruk. Kenapa ini soalan besar?

Kita perlu menetapkan pilihan signalWrites kepada benar untuk menetapkan kuantiti isyarat. Ini disebabkan salah tafsir masalah yang diberikan.
Dalam kes kami, kami ingin menyegerakkan dua pembolehubah yang, dalam pewujudan kami, dinyahsegerakkan

Kaunter tidak bergantung pada buah, yang merupakan sumber awal kami. Pada hakikatnya, di sini kita mempunyai keadaan komponen, yang sumber awalnya adalah buah dan selebihnya adalah terbitan buah.

Realisasikan masalah seperti berikut

@Component({
  template: `<button type="button" (click)="updateQuantity()"> 
    {{fruitState().quantity()}}
    </button>`
})
export class QuantityComponent() {
  fruit = input.required<string>();

  fruitState = computed(() => ({
    source: fruit(),
    quantity: signal(1),
  }));

  updateQuantity(): void {
    this.fruitState().quantity.update(prevCount => prevCount++);
  }
}
Salin selepas log masuk
Salin selepas log masuk

Penciptaan ini sangat mengaitkan buah dengan kuantitinya.
Jadi sebaik sahaja buah berubah, fruitState pembolehubah yang dikira dikira semula secara automatik. Pengiraan semula ini mengembalikan objek dengan sifat kuantiti, iaitu isyarat yang dimulakan kepada 1.

Dengan mengembalikan isyarat, pembolehubah boleh dinaikkan pada klik dan hanya menetapkan semula apabila buah berubah.

Ia adalah corak yang agak mudah untuk disediakan, tetapi tidakkah kita boleh memudahkannya?

Fungsi LinkedSignal untuk menyelamatkan.

Dengan ketibaan Angular 19, fungsi baharu untuk mengira isyarat terbitan.

Sehingga kini, kami mempunyai fungsi yang dikira, tetapi fungsi ini mengembalikan Isyarat dan bukan WrittableSignal, yang mungkin praktikal dalam kes penggunaan kami sebelum ini untuk pembolehubah kuantiti.

Di sinilah LinkedSignal masuk. LinkedSignal, seperti namanya, membolehkan anda memautkan dua isyarat dengan kuat bersama-sama.

Jika kita kembali ke kes sebelumnya, fungsi ini akan membolehkan kita memudahkan kod seperti berikut:

@Component({
  template: `<button type="button" (click)="updateQuantity()"> 
    {{quantity()}}
    </button>`
})
export class QuantityComponent() {
  fruit = input.required<string>();
  quantity = linkedSignal({ source: fruit, computation: () => 1 });

  updateQuantity(): void {
    this.quantity.update(prevCount => prevCount++);
  }
}
Salin selepas log masuk
Salin selepas log masuk

Fungsi linkedSignal ditakrifkan seperti berikut:

linkedSignal(computation: () => D, options?: { equal?: ValueEqualityFn<NoInfer<D>>; }): WritableSignal<D>;

linkedSignal(options: { source: () => S; computation: (source: NoInfer<S>, previous?: { source: NoInfer<S>; value: NoInfer<D>; }) => D; equal?: ValueEqualityFn<NoInfer<D>>; }): WritableSignal<D>;
Salin selepas log masuk
Salin selepas log masuk

Dalam takrif pertama, takrifan "disingkat", fungsi linkedSignal mengambil fungsi pengiraan sebagai parameter dan objek konfigurasi.

@Component({
  template: `<button type="button" (click)="updateQuantity()"> 
    {{quantity()}}
    </button>`
})
export class QuantityComponent() {
  fruit = input.required<string>();
  count = signal(1);

  updateQuantity(): void {
    this.count.update(prevCount => prevCount++);
  }
}
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Dalam contoh sebelumnya ini, kerana fungsi pengiraan bergantung kepada kuantiti sigal, apabila kuantiti berubah, fungsi pengiraan dinilai semula.

Dalam definisi kedua, kaedah linkedFunction mengambil objek sebagai parameter dengan tiga sifat

  • sumber: isyarat di mana fungsi pengiraan mendasarkan penilaian semulanya
  • fungsi pengiraan
  • objek parameter

Bertentangan dengan fungsi pengiraan "disingkat", di sini fungsi pengiraan mengambil sebagai parameter nilai sumber dan "pendahuluan".

@Component({
  template: `<button type="button" (click)="updateQuantity()"> 
    {{quantity()}}
    </button>`
})
export class QuantityComponent() {
  fruit = input.required<string>();
  quantity = signal(1);

  countEffect(() => {
    this.fruit();
    this.quantity.set(1);
  }, { allowSignalWrites: true })

  updateQuantity(): void {
    this.quantity.update(prevCount => prevCount++);
  }
}
Salin selepas log masuk
Salin selepas log masuk

Api Sumber baharu

Angular 19 akan memperkenalkan API baharu untuk pengambilan data mudah dan mendapatkan semula status pertanyaan (belum selesai dll), data dan ralat.

Bagi mereka yang agak biasa dengan rangka kerja, API baharu ini berfungsi sedikit seperti cangkuk useRessource.

Mari kita lihat contoh:

@Component({
  template: `<button type="button" (click)="updateQuantity()"> 
    {{fruitState().quantity()}}
    </button>`
})
export class QuantityComponent() {
  fruit = input.required<string>();

  fruitState = computed(() => ({
    source: fruit(),
    quantity: signal(1),
  }));

  updateQuantity(): void {
    this.fruitState().quantity.update(prevCount => prevCount++);
  }
}
Salin selepas log masuk
Salin selepas log masuk

Terdapat beberapa perkara yang perlu diketahui tentang coretan kod ini

Terdapat beberapa perkara yang perlu diperhatikan dalam kod coretan ini:

  • secara lalai, pemuat mengambil janji sebagai parameter
  • jenis fruitRessource ialah WrittableRessource, yang membolehkan kami mengubah suai data secara setempat jika diperlukan
  • permintaan untuk butiran buah dihantar terus ke pelayan apabila sumber fuitResource dibuat
  • this.fruitId() tidak dijejaki dalam pemuat, jadi tiada permintaan baharu akan dihantar jika fruitId berubah
  • WrittableRessource mempunyai kaedah muat semula untuk memuat semula data

Kesan berikut akan mencetak nilai tersebut

@Component({
  template: `<button type="button" (click)="updateQuantity()"> 
    {{quantity()}}
    </button>`
})
export class QuantityComponent() {
  fruit = input.required<string>();
  quantity = linkedSignal({ source: fruit, computation: () => 1 });

  updateQuantity(): void {
    this.quantity.update(prevCount => prevCount++);
  }
}
Salin selepas log masuk
Salin selepas log masuk

seperti yang dijelaskan di atas, secara lalai isyarat fruitId tidak dijejaki.

Jadi bagaimana anda memulakan semula permintaan http setiap kali nilai isyarat ini berubah, tetapi juga bagaimana anda membatalkan permintaan sebelumnya sekiranya nilai isyarat fruitId berubah dan tindak balas kepada permintaan sebelumnya tidak tiba?

Fungsi sumber mengambil sifat lain yang dipanggil permintaan.

Hartanah ini mengambil sebagai nilainya fungsi yang bergantung pada isyarat dan mengembalikan nilainya.

linkedSignal(computation: () => D, options?: { equal?: ValueEqualityFn<NoInfer<D>>; }): WritableSignal<D>;

linkedSignal(options: { source: () => S; computation: (source: NoInfer<S>, previous?: { source: NoInfer<S>; value: NoInfer<D>; }) => D; equal?: ValueEqualityFn<NoInfer<D>>; }): WritableSignal<D>;
Salin selepas log masuk
Salin selepas log masuk

Seperti yang ditunjukkan dalam kod di atas, fungsi pemuat mengambil dua parameter

  • nilai permintaan: di sini nilai isyarat fruitId
  • nilai sifat isyarat objek abortController yang digunakan untuk membatalkan permintaan http.

Jadi jika nilai isyarat fruitId berubah semasa httpRequest mendapatkan semula butiran buah, permintaan akan dibatalkan untuk melancarkan permintaan baharu.

Akhirnya, Angular juga telah memikirkan kemungkinan untuk menggabungkan api baharu ini dengan RxJs, membolehkan kami mendapat manfaat daripada kuasa pengendali Rx.

Kesalinghubungan dicapai menggunakan fungsi rxResource, yang ditakrifkan dengan cara yang sama seperti fungsi sumber.
Satu-satunya perbezaan ialah jenis pemulangan sifat pemuat, yang akan mengembalikan pemerhatian

@Component({
  template: `<button type="button" (click)="updateQuantity()"> 
    {{quantity()}}
    </button>`
})
export class QuantityComponent() {
  fruit = input.required<string>();
  count = signal(1);

  updateQuantity(): void {
    this.count.update(prevCount => prevCount++);
  }
}
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Di sini tidak perlu mempunyai abortSignal, pembatalan permintaan sebelumnya apabila nilai perubahan fruitId isyarat tersirat dalam fungsi rxResource dan tingkah laku akan sama dengan operator switchMap.

Atas ialah kandungan terperinci Peningkatan seterusnya dalam kereaktifan sudut. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:dev.to
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan