Pengeluaran Angular v19, hanya beberapa minggu yang lalu, menandakan peristiwa penting dalam revolusi isyarat dalam rangka kerja, dengan Input, Model, Output dan Pertanyaan Isyarat API kini secara rasmi dinaikkan pangkat kepada stabil.
Tetapi bukan itu sahaja! Versi utama ini juga memperkenalkan alatan baharu berkuasa yang direka untuk memajukan lagi revolusi isyarat: API Sumber baharu.
Seperti namanya, API Sumber baharu ini direka untuk memudahkan pemuatan sumber tak segerak dengan memanfaatkan kuasa penuh isyarat!
PENTING: pada masa penulisan, API Sumber baharu masih dalam percubaan. Ini bermakna ia mungkin berubah sebelum menjadi stabil, jadi gunakannya atas risiko anda sendiri. ?
Mari kita mendalami cara ia berfungsi dan cara ia memudahkan pengendalian sumber tak segerak!
Kebanyakan API isyarat adalah segerak, tetapi dalam aplikasi dunia nyata, adalah penting untuk mengendalikan sumber tak segerak, seperti mengambil data daripada pelayan atau mengurus interaksi pengguna dalam masa nyata.
Di sinilah API Sumber baharu dimainkan.
Menggunakan Sumber, anda boleh menggunakan sumber tak segerak melalui isyarat dengan mudah, membolehkan anda mengurus pengambilan data dengan mudah, mengendalikan keadaan pemuatan dan mencetuskan pengambilan baharu apabila parameter isyarat yang berkaitan berubah.
Cara lebih mudah untuk mencipta Sumber ialah dengan menggunakan fungsi sumber():
import { resource, signal } from '@angular/core'; const RESOURCE_URL = 'https://jsonplaceholder.typicode.com/todos/'; private id = signal(1); private myResource = resource({ request: () => ({ id: this.id() }), loader: ({ request }) => fetch(RESOURCE_URL + request.id), });
Fungsi ini menerima ResourceOptions objek konfigurasi sebagai input, membolehkan anda menentukan sifat berikut:
Terima kasih kepada konfigurasi ini, kami boleh dengan mudah mentakrifkan pergantungan tak segerak yang akan sentiasa digunakan dengan cekap dan sentiasa dikemas kini.
Setelah Sumber dicipta, fungsi pemuat dilaksanakan, kemudian permintaan tak segerak yang terhasil bermula:
import { resource, signal } from '@angular/core'; const RESOURCE_URL = 'https://jsonplaceholder.typicode.com/todos/'; private id = signal(1); private myResource = resource({ request: () => ({ id: this.id() }), loader: ({ request }) => fetch(RESOURCE_URL + request.id), });
Apabila isyarat bahawa fungsi permintaan bergantung pada perubahan, fungsi permintaan berjalan semula dan jika ia mengembalikan parameter baharu, fungsi pemuat dicetuskan untuk mengambil nilai sumber yang dikemas kini:
import { resource, signal } from "@angular/core"; const RESOURCE_URL = "https://jsonplaceholder.typicode.com/todos/"; const id = signal(1); const myResource = resource({ request: () => ({ id: id() }), loader: ({ request }) => fetch(RESOURCE_URL + request.id) }); console.log(myResource.status()); // Prints: 2 (which means "Loading")
Jika tiada fungsi permintaan disediakan, fungsi pemuat akan dijalankan sekali sahaja, melainkan Sumber dimuat semula menggunakan muat semula kaedah (lebih banyak di bawah).
Akhir sekali, sebaik sahaja komponen induk atau perkhidmatan dimusnahkan, Sumber juga dimusnahkan melainkan penyuntik khusus telah disediakan.
Dalam kes sedemikian, Sumber akan kekal aktif dan dimusnahkan hanya apabila penyuntik yang disediakan itu sendiri dimusnahkan.
Untuk mengoptimumkan pengambilan data, Sumber boleh membatalkan permintaan tertunggak jika pengiraan permintaan() berubah semasa nilai sebelumnya masih dimuatkan.
Untuk mengurus ini, fungsi pemuat() menyediakan Isyarat abort, yang boleh anda hantar kepada permintaan berterusan, seperti ambil. Permintaan mendengar abortSignal dan membatalkan operasi jika ia dicetuskan, memastikan pengurusan sumber yang cekap dan menghalang permintaan rangkaian yang tidak perlu:
import { resource, signal } from "@angular/core"; const RESOURCE_URL = "https://jsonplaceholder.typicode.com/todos/"; const id = signal(1); const myResource = resource({ request: () => ({ id: id() }), loader: ({ request }) => fetch(RESOURCE_URL + request.id) }); console.log(myResource.status()); // Prints: 2 (which means "Loading") // After the fetch resolves console.log(myResource.status()); // Prints: 4 (which means "Resolved") console.log(myResource.value()); // Prints: { "id": 1 , ... } id.set(2); // Triggers a request, causing the loader function to run again console.log(myResource.status()); // Prints: 2 (which means "Loading") // After the fetch resolves console.log(myResource.status()); // Prints: 4 (which means "Resolved") console.log(myResource.value()); // Prints: { "id": 2 , ... }
Berdasarkan perkara ini, disyorkan untuk menggunakan API Sumber terutamanya untuk permintaan GET, kerana ia biasanya selamat untuk dibatalkan tanpa menyebabkan masalah.
Untuk permintaan POST atau KEMASKINI, pembatalan mungkin membawa kepada kesan sampingan yang tidak diingini, seperti penyerahan atau kemas kini data yang tidak lengkap. Walau bagaimanapun, jika anda memerlukan kefungsian yang serupa untuk jenis permintaan ini, anda boleh menggunakan kaedah effect() untuk mengurus operasi dengan selamat.
API Sumber menyediakan beberapa sifat isyarat untuk keadaannya, yang boleh anda gunakan dengan mudah secara langsung dalam komponen atau perkhidmatan anda:
Berikut ialah contoh cara menggunakan Sumber dalam komponen:
import { resource, signal } from '@angular/core'; const RESOURCE_URL = 'https://jsonplaceholder.typicode.com/todos/'; private id = signal(1); private myResource = resource({ request: () => ({ id: this.id() }), loader: ({ request }) => fetch(RESOURCE_URL + request.id), });
Dalam contoh ini, Sumber digunakan untuk mengambil data daripada API berdasarkan nilai isyarat id, yang boleh ditambah dengan mengklik butang.
Setiap kali pengguna mengklik butang, nilai isyarat id berubah, mencetuskan fungsi pemuat untuk mengambil item baharu daripada API jauh.
UI secara automatik mengemas kini dengan data yang diambil terima kasih kepada sifat isyarat yang didedahkan oleh API Sumber.
Seperti yang dinyatakan sebelum ini, isyarat status memberikan maklumat tentang keadaan semasa sumber pada bila-bila masa tertentu.
Nilai yang mungkin bagi isyarat status ditakrifkan oleh enum ResourceStatus. Berikut ialah ringkasan status ini dan nilai sepadannya:
Status ini membantu menjejaki kemajuan Sumber dan memudahkan pengendalian operasi tak segerak dalam aplikasi anda dengan lebih baik.
Memandangkan kerumitan status ini, API Sumber menyediakan kaedah hasValue(), yang mengembalikan boolean berdasarkan status semasa.
Ini memastikan maklumat yang tepat tentang status Sumber, menyediakan cara yang lebih dipercayai untuk mengendalikan operasi tak segerak tanpa bergantung pada nilai, yang mungkin tidak ditentukan di negeri tertentu.
import { resource, signal } from '@angular/core'; const RESOURCE_URL = 'https://jsonplaceholder.typicode.com/todos/'; private id = signal(1); private myResource = resource({ request: () => ({ id: this.id() }), loader: ({ request }) => fetch(RESOURCE_URL + request.id), });
Kaedah ini reaktif, membolehkan anda menggunakan dan menjejakinya seperti isyarat.
API Sumber juga menyediakan isyarat sedangMemuatkan, yang mengembalikan sama ada sumber itu sedang dalam keadaan Memuatkan atau Memuatkan Semula:
import { resource, signal } from "@angular/core"; const RESOURCE_URL = "https://jsonplaceholder.typicode.com/todos/"; const id = signal(1); const myResource = resource({ request: () => ({ id: id() }), loader: ({ request }) => fetch(RESOURCE_URL + request.id) }); console.log(myResource.status()); // Prints: 2 (which means "Loading")
Memandangkan isLoading ialah isyarat yang dikira, ia boleh dijejaki secara reaktif, membolehkan anda memantau keadaan pemuatan dalam masa nyata menggunakan API isyarat.
Isyarat nilai yang disediakan oleh Sumber ialah WritableSignal, yang membolehkan anda mengemas kini secara manual menggunakan set() dan kemas kini( ) fungsi:
import { resource, signal } from "@angular/core"; const RESOURCE_URL = "https://jsonplaceholder.typicode.com/todos/"; const id = signal(1); const myResource = resource({ request: () => ({ id: id() }), loader: ({ request }) => fetch(RESOURCE_URL + request.id) }); console.log(myResource.status()); // Prints: 2 (which means "Loading") // After the fetch resolves console.log(myResource.status()); // Prints: 4 (which means "Resolved") console.log(myResource.value()); // Prints: { "id": 1 , ... } id.set(2); // Triggers a request, causing the loader function to run again console.log(myResource.status()); // Prints: 2 (which means "Loading") // After the fetch resolves console.log(myResource.status()); // Prints: 4 (which means "Resolved") console.log(myResource.value()); // Prints: { "id": 2 , ... }
Nota: seperti yang anda lihat, mengemas kini nilai isyarat secara manual juga akan menetapkan status kepada 5, yang bermaksud "Setempat ", untuk menunjukkan bahawa nilai telah ditetapkan secara setempat.
Nilai yang ditetapkan secara manual akan kekal sehingga nilai baharu ditetapkan atau permintaan baharu dilaksanakan, yang akan menggantikannya dengan nilai baharu:
import { resource, signal } from "@angular/core"; const RESOURCE_URL = "https://jsonplaceholder.typicode.com/todos/"; const id = signal(1); const myResource = resource({ request: () => ({ id: id() }), loader: ({ request, abortSignal }) => fetch(RESOURCE_URL + request.id, { signal: abortSignal }) }); console.log(myResource.status()); // Prints: 2 (which means "Loading") // Triggers a new request, causing the previous fetch to be aborted // Then the loader function to run again generating a new fetch request id.set(2); console.log(myResource.status()); // Prints: 2 (which means "Loading")
Nota: isyarat nilai API Sumber menggunakan corak yang sama API LinkedSignal baharu, tetapi tidak menggunakan ia di bawah tudung. ?
Untuk memudahkan penggunaan isyarat nilai, API Sumber menyediakan pembalut kemudahan untuk set, kemas kini dan sebagaiReadonly kaedah.
Kaedah asReadonly amat berguna kerana ia mengembalikan contoh baca sahaja bagi isyarat nilai, membenarkan akses hanya untuk membaca dan menghalang sebarang pengubahsuaian yang tidak disengajakan.
Anda boleh menggunakan pendekatan ini untuk mencipta perkhidmatan yang mengurus dan menjejaki perubahan kepada nilai sumber dengan mengeksport contoh baca sahaja bagi nilai:
import { Component, resource, signal } from '@angular/core'; const BASE_URL = 'https://jsonplaceholder.typicode.com/todos/'; @Component({ selector: 'my-component', template: ` @if (myResource.value()) { {{ myResource.value().title }} } <button (click)="fetchNext()">Fetch next item</button> ` }) export class MyComponent { private id = signal(1); protected myResource = resource({ request: () => ({ id: this.id() }), loader: ({ request }) => fetch(BASE_URL + request.id).then((response) => response.json()), }); protected fetchNext(): void { this.id.update((id) => id + 1); } }
Ini akan menghalang pengguna daripada mengubah suai nilai, mengurangkan risiko perubahan yang tidak diingini, meningkatkan konsistensi dalam pengurusan data yang kompleks.
Apabila bekerja dengan sumber tak segerak, anda mungkin menghadapi senario di mana menyegarkan semula data atau memusnahkan Sumber menjadi perlu.
Untuk mengendalikan senario ini, API Sumber menyediakan dua kaedah khusus yang menawarkan penyelesaian yang cekap untuk mengurus tindakan ini.
Kaedah muat semula() mengarahkan Sumber untuk melaksanakan semula permintaan tak segerak, memastikan ia mengambil data yang paling terkini:
import { resource, signal } from '@angular/core'; const RESOURCE_URL = 'https://jsonplaceholder.typicode.com/todos/'; private id = signal(1); private myResource = resource({ request: () => ({ id: this.id() }), loader: ({ request }) => fetch(RESOURCE_URL + request.id), });
Kaedah muat semula() mengembalikan benar jika muat semula berjaya dimulakan.
Jika muat semula tidak dapat dilakukan, sama ada kerana ia tidak perlu, seperti apabila status sudah Memuatkan atau Muat semula, atau tidak disokong, seperti apabila status Terbiar, kaedah mengembalikan palsu.
Kaedah musnah() secara manual memusnahkan Sumber, memusnahkan sebarang effect() yang digunakan untuk menjejaki perubahan permintaan, membatalkan sebarang permintaan yang belum selesai dan menetapkan status kepada Melahu sambil menetapkan semula nilai kepada tidak ditentukan:
import { resource, signal } from "@angular/core"; const RESOURCE_URL = "https://jsonplaceholder.typicode.com/todos/"; const id = signal(1); const myResource = resource({ request: () => ({ id: id() }), loader: ({ request }) => fetch(RESOURCE_URL + request.id) }); console.log(myResource.status()); // Prints: 2 (which means "Loading")
Selepas Sumber dimusnahkan, ia tidak akan membalas permintaan perubahan atau operasi muat semula().
Nota: pada ketika ini, manakala isyarat nilai kekal boleh ditulis, Sumber akan kehilangan tujuan yang dimaksudkan dan tidak lagi berfungsi fungsinya, menjadi tidak berguna . ?
Seperti hampir semua API berasaskan isyarat yang diperkenalkan setakat ini, API Sumber juga menawarkan utiliti saling kendali untuk penyepaduan yang lancar dengan RxJS.
Daripada menggunakan kaedah resource() untuk mencipta Resource berasaskan Promise, anda boleh menggunakan kaedah rxResource() untuk menggunakan Boleh diperhatikan:
import { resource, signal } from "@angular/core"; const RESOURCE_URL = "https://jsonplaceholder.typicode.com/todos/"; const id = signal(1); const myResource = resource({ request: () => ({ id: id() }), loader: ({ request }) => fetch(RESOURCE_URL + request.id) }); console.log(myResource.status()); // Prints: 2 (which means "Loading") // After the fetch resolves console.log(myResource.status()); // Prints: 4 (which means "Resolved") console.log(myResource.value()); // Prints: { "id": 1 , ... } id.set(2); // Triggers a request, causing the loader function to run again console.log(myResource.status()); // Prints: 2 (which means "Loading") // After the fetch resolves console.log(myResource.status()); // Prints: 4 (which means "Resolved") console.log(myResource.value()); // Prints: { "id": 2 , ... }
Nota: kaedah rxResource() sebenarnya didedahkan oleh pakej rxjs-interop.
Fungsi Boleh diperhatikan yang dihasilkan oleh fungsi pemuat() hanya akan mempertimbangkan nilai yang pertama dipancarkan, mengabaikan pelepasan berikutnya.
Terima kasih semua kerana mengikuti saya sepanjang 2024 yang indah ini. ??
Ia telah menjadi tahun yang penuh dengan cabaran, tetapi juga sangat bermanfaat. Saya mempunyai rancangan besar untuk tahun 2025 dan saya tidak sabar untuk mula mengerjakannya. ?
Saya ingin mendapatkan maklum balas anda jadi sila tinggalkan ulasan, suka atau ikuti. ?
Kemudian, jika anda benar-benar menyukainya, kongsi di kalangan komuniti anda, rakan teknologi dan sesiapa sahaja yang anda mahukan. Dan jangan lupa untuk ikuti saya di LinkedIn. ??
Atas ialah kandungan terperinci Angular resource() dan rxResource() API: perkara yang anda perlu tahu. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!