Die Veröffentlichung von Angular v19 vor wenigen Wochen markiert mit dem Input, Modell, Ausgabe und Signal Abfragen APIs jetzt offiziell auf stabil hochgestuft.
Aber das ist noch nicht alles! Diese Hauptversion führt außerdem leistungsstarke neue Tools ein, die die Signalrevolution weiter vorantreiben sollen: die neueRessourcen-API.
Wie der Name schon sagt, ist diese neueRessourcen-API darauf ausgelegt, das Laden von asynchronen Ressourcen zu vereinfachen, indem die volle Leistungsfähigkeit der Signale genutzt wird!
Sehen wir uns an, wie es funktioniert und wie es den Umgang mit asynchronen Ressourcen vereinfacht!WICHTIG: zum Zeitpunkt des Schreibens ist die neue Ressourcen-API noch experimentell. Dies bedeutet, dass es sich ändern kann, bevor es stabil wird. Die Verwendung erfolgt daher auf eigenes Risiko. ?
Hier kommt die neue
Ressource API ins Spiel.
Mithilfe einerRessource können Sie problemlos eine asynchrone Ressource über Signale nutzen, sodass Sie den Datenabruf einfach verwalten, Ladezustände verwalten und einen neuen Abruf auslösen können, wenn sich die zugehörigen Signalparameter ändern.
resources( ) FunktionRessource zu erstellen, ist die Verwendung der Funktion resource():
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), });
ResourceOptions-Konfigurationsobjekt als Eingabe, sodass Sie die folgenden Eigenschaften angeben können:
asynchrone Abhängigkeit definieren, die immer effizient genutzt und auf dem neuesten Stand gehalten wird.
Sobald eine Ressource erstellt wurde, wird die Loader-Funktion ausgeführt, dann wird die resultierende asynchrone Anfrage gestartet:
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), });
Immer wenn ein Signal vorliegt, dass die Funktion Anfrage von Änderungen abhängt, wird die Funktion Anfrage erneut ausgeführt, und wenn neue Parameter zurückgegeben werden, wird die Funktion Loader ausgelöst um den Wert der aktualisierten Ressource abzurufen:
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")
Wenn keine Request-Funktion bereitgestellt wird, wird die Loader-Funktion nur einmal ausgeführt, es sei denn, die Ressource wird mithilfe von reload neu geladen Methode (mehr unten).
Sobald schließlich die übergeordnete Komponente oder der übergeordnete Dienst zerstört ist, wird auch die Ressource zerstört, es sei denn, es wurde ein bestimmter Injektor bereitgestellt.
In solchen Fällen bleibt die Ressource aktiv und wird nur dann zerstört, wenn der bereitgestellte Injektor selbst zerstört wird.
Um den Datenabruf zu optimieren, kann eine Ressource ausstehende Anforderungen abbrechen, wenn sich die request()-Berechnung ändert, während ein vorheriger Wert noch geladen wird.
Um dies zu verwalten, stellt die Funktion loader() ein abortSignal bereit, das Sie an laufende Anforderungen wie fetch übergeben können. Die Anfrage wartet auf das abortSignal und bricht den Vorgang ab, wenn er ausgelöst wird, wodurch eine effiziente Ressourcenverwaltung gewährleistet und unnötige Netzwerkanfragen verhindert werden:
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 , ... }
Auf dieser Grundlage wird empfohlen, die Ressourcen-API hauptsächlich für GET-Anfragen zu verwenden, da diese normalerweise ohne Probleme abgebrochen werden können.
Bei POST- oder UPDATE-Anfragen kann das Abbrechen zu unbeabsichtigten Nebenwirkungen führen, wie etwa unvollständigen Datenübermittlungen oder Aktualisierungen. Wenn Sie jedoch eine ähnliche Funktionalität für diese Art von Anfragen benötigen, können Sie die Methode effect() verwenden, um die Vorgänge sicher zu verwalten.
Die Ressource-API stellt mehrere Signaleigenschaften für ihren Zustand bereit, die Sie problemlos direkt in Ihren Komponenten oder Diensten verwenden können:
Ressource innerhalb einer Komponente genutzt wird:
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), });
Ressource verwendet, um Daten von einer API basierend auf dem Wert des id-Signals abzurufen, der durch Klicken auf eine Schaltfläche erhöht werden kann.
Immer wenn der Benutzer auf die Schaltfläche klickt, ändert sich der Signalwertid und löst die Funktion Loader aus, um ein neues Element von der Remote-API abzurufen.
Die Benutzeroberfläche wird dank der von derRessource-API bereitgestellten Signaleigenschaften automatisch mit den abgerufenen Daten aktualisiert.
Status jederzeit Informationen über den aktuellen Status der Ressource.
Die möglichen Werte desstatus-Signals werden durch die ResourceStatus-Enumeration definiert. Hier ist eine Zusammenfassung dieser Status und ihrer entsprechenden Werte:
Ressource zu verfolgen und ermöglichen eine bessere Handhabung asynchroner Vorgänge in Ihrer Anwendung.
Angesichts der Komplexität dieser Status stellt die Ressourcen-API eine Methode hasValue() bereit, die einen booleschen Wert basierend auf dem aktuellen Status zurückgibt.
Dies stellt genaue Informationen über den Status der Ressource sicher und bietet eine zuverlässigere Möglichkeit, asynchrone Vorgänge abzuwickeln, ohne sich auf den Wert zu verlassen, der in bestimmten Zuständen undefiniert sein könnte.
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), });
Diese Methode ist reaktiv und ermöglicht es Ihnen, sie wie ein Signal zu konsumieren und zu verfolgen.
Die Ressource-API stellt außerdem ein isLoading-Signal bereit, das zurückgibt, ob sich die Ressource derzeit im Status Laden oder Neuladen befindet:
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")
Da es sich bei isLoading um ein berechnetes Signal handelt, kann es reaktiv verfolgt werden, sodass Sie den Ladezustand mithilfe von Signal-APIs in Echtzeit überwachen können.
Das von einer Ressource bereitgestellte Wertsignal ist ein WritableSignal, das es Ihnen ermöglicht, es manuell mit set() und update( zu aktualisieren. )Funktionen:
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 , ... }
Hinweis: Wie Sie sehen können, wird durch die manuelle Aktualisierung des Werts des Signals auch der Status auf 5 gesetzt, was „Lokal“ bedeutet “, um anzuzeigen, dass der Wert lokal festgelegt wurde.
Der manuell festgelegte Wert bleibt bestehen, bis entweder ein neuer Wert festgelegt oder eine neue Anfrage ausgeführt wird, die ihn mit einem neuen Wert überschreibt:
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")
Hinweis:Das Wert-Signal der Ressourcen-API verwendet dasselbe Muster der neuen LinkedSignal-API, jedoch nicht es unter der Haube. ?
Um die Verwendung des value-Signals zu vereinfachen, stellt die Resource-API praktische Wrapper für set, update und asReadonly Methoden.
Die MethodeasReadonly ist besonders nützlich, da sie eine schreibgeschützte Instanz des Signals value zurückgibt, den Zugriff nur zum Lesen ermöglicht und versehentliche Änderungen verhindert.
Mit diesem Ansatz können Sie Dienste erstellen, die Änderungen an Ressourcenwerten verwalten und verfolgen, indem Sie eine schreibgeschützte Instanz desWerts: exportieren
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); } }
Bei der Arbeit mit asynchronen Ressourcen kann es vorkommen, dass eine Aktualisierung der Daten oder die Zerstörung der Ressource erforderlich wird.
Um diese Szenarien zu bewältigen, stellt die Ressourcen-API zwei dedizierte Methoden bereit, die effiziente Lösungen für die Verwaltung dieser Aktionen bieten.
Die Methode reload() weist die Ressource an, die asynchrone Anforderung erneut auszuführen, um sicherzustellen, dass sie die aktuellsten Daten abruft:
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), });
Die Methode reload() gibt true zurück, wenn ein Neuladen erfolgreich initiiert wurde.
Wenn ein Neuladen nicht durchgeführt werden kann, weil es entweder unnötig ist, z. B. wenn der Status bereits Laden oder Neuladen lautet, oder weil es nicht unterstützt wird, z. B. wenn der Status lautet Im Leerlauf gibt die Methode false zurück.
Die Methode destroy() zerstört manuell die Ressource, zerstört alle effect(), die zum Verfolgen von Anforderungsänderungen verwendet werden, storniert alle ausstehenden Anforderungen und legt die fest Status auf Leerlauf, während der Wert auf zurückgesetzt wird undefiniert:
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")
Nachdem eine Ressource zerstört wurde, reagiert sie nicht mehr auf Anforderungsänderungen oder reload()-Vorgänge.
Hinweis: Zu diesem Zeitpunkt verliert die Ressource ihren beabsichtigten Zweck, erfüllt nicht mehr ihre Funktion und wird unbrauchbar, während das Signal Wert beschreibbar bleibt . ?
Wie fast alle bisher eingeführten signalbasierten APIs bietet auch die Resource API ein Interoperabilitätsdienstprogramm für die nahtlose Integration mit RxJS.
Anstatt die Methode resource() zum Erstellen einer Promise-basierten Ressource zu verwenden, können Sie die Methode rxResource() verwenden, um zu verwenden Observable:
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 , ... }
Hinweis:Die Methode rxResource() wird tatsächlich durch das Paket rxjs-interop verfügbar gemacht.
Das von der Funktion loader() erzeugte Observable berücksichtigt nur den ersten ausgegebenen Wert und ignoriert nachfolgende Emissionen.
Vielen Dank an alle, die mir in diesem wundervollen Jahr 2024 gefolgt sind. ??
Es war ein Jahr voller Herausforderungen, aber auch sehr lohnend. Ich habe große Pläne für 2025 und kann es kaum erwarten, mit der Arbeit daran zu beginnen. ?
Ich freue mich über Ihr Feedback, also hinterlassen Sie bitte einen Kommentar, Gefällt mir oder Folgen. ?
Wenn es Ihnen dann wirklich gefallen hat, teilen Sie es mit Ihrer Community, Ihren Tech-Brüdern und wem auch immer Sie möchten. Und vergessen Sie nicht, mir auf LinkedIn zu folgen. ??
Das obige ist der detaillierte Inhalt vonAngular-APIs „resource()' und „rxResource()': Was Sie wissen müssen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!