Heim > Web-Frontend > js-Tutorial > Angular-APIs „resource()' und „rxResource()': Was Sie wissen müssen

Angular-APIs „resource()' und „rxResource()': Was Sie wissen müssen

DDD
Freigeben: 2025-01-04 06:52:43
Original
474 Leute haben es durchsucht

Angular resource() and rxResource() APIs: what you need to know

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 neue

Ressourcen-API.

Wie der Name schon sagt, ist diese neue

Ressourcen-API darauf ausgelegt, das Laden von asynchronen Ressourcen zu vereinfachen, indem die volle Leistungsfähigkeit der Signale genutzt wird!

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. ?

Sehen wir uns an, wie es funktioniert und wie es den Umgang mit asynchronen Ressourcen vereinfacht!


Die Ressourcen-API

Die meisten Signal-APIs sind synchron, aber in realen Anwendungen ist es wichtig, asynchrone Ressourcen zu verarbeiten, wie zum Beispiel das Abrufen von Daten von einem Server oder die Verwaltung von Benutzerinteraktionen in Echtzeit.

Hier kommt die neue

Ressource API ins Spiel.

Mithilfe einer

Ressource 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( ) Funktion

Der einfachere Weg, eine

Ressource 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),
});
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Diese Funktion akzeptiert ein

ResourceOptions-Konfigurationsobjekt als Eingabe, sodass Sie die folgenden Eigenschaften angeben können:

  • Anfrage: eine reaktive Funktion, die die Parameter bestimmt, die zum Ausführen der Anfrage an die asynchrone Ressource verwendet werden;
  • Loader: eine Ladefunktion, die ein Promise des Ressourcenwerts zurückgibt, optional basierend auf den bereitgestellten Anfrage-Parametern. Dies ist die einzige erforderliche Eigenschaft von ResourceOptions;
  • equal: Gleichheitsfunktion, die zum Vergleichen des Rückgabewerts des Loaders verwendet wird;
  • Injektor: überschreibt den Injektor, der von der Ressource-Instanz verwendet wird, um sich selbst zu zerstören, wenn die übergeordnete Komponente oder der übergeordnete Dienst zerstört wird.
Dank dieser Konfigurationen können wir ganz einfach eine

asynchrone Abhängigkeit definieren, die immer effizient genutzt und auf dem neuesten Stand gehalten wird.

Ressourcenlebenszyklus

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),
});
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

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")
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

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.

Anfragen mit abortSignal abbrechen

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 , ... }
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

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.


So verbrauchen Sie eine Ressource

Die Ressource-API stellt mehrere Signaleigenschaften für ihren Zustand bereit, die Sie problemlos direkt in Ihren Komponenten oder Diensten verwenden können:

  • Wert: enthält den aktuellen Wert der Ressource oder undefiniert, wenn kein Wert verfügbar ist. Als WritableSignal kann es manuell aktualisiert werden;
  • Status: enthält den aktuellen Status der Ressource und gibt an, was die Ressource tut und was von ihrem Wert;
  • Fehler: Im Fehlerstatus enthält es den letzten Fehler, der während des Ladens der Ressource aufgetreten ist;
  • isLoading: gibt an, ob die Ressource einen neuen Wert lädt oder den vorhandenen neu lädt.
Hier ist ein Beispiel dafür, wie eine

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),
});
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
In diesem Beispiel wird die

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 Signalwert

id und löst die Funktion Loader aus, um ein neues Element von der Remote-API abzurufen.

Die Benutzeroberfläche wird dank der von der

Ressource-API bereitgestellten Signaleigenschaften automatisch mit den abgerufenen Daten aktualisiert.


Überprüfen Sie den Status einer Ressource

Wie bereits erwähnt, liefert das Signal

Status jederzeit Informationen über den aktuellen Status der Ressource.

Die möglichen Werte des

status-Signals werden durch die ResourceStatus-Enumeration definiert. Hier ist eine Zusammenfassung dieser Status und ihrer entsprechenden Werte:

    Idle =
  • 0: Die Ressource hat keine gültige Anfrage und führt keinen Ladevorgang durch. value() ist undefiniert;
  • Fehler =
  • 1: Der Ladevorgang ist mit einem Fehler fehlgeschlagen. value() ist undefiniert;
  • Loading =
  • 2: Die Ressource lädt derzeit aufgrund einer Änderung in ihrer Anfrage einen neuen Wert. value() ist undefiniert;
  • Reloading =
  • 3: Die Ressource lädt derzeit einen neuen Wert für dieselbe Anfrage neu. value() gibt weiterhin den zuvor abgerufenen Wert zurück, bis der Neuladevorgang abgeschlossen ist;
  • Gelöst =
  • 4: Der Ladevorgang ist abgeschlossen. value() enthält den vom Loader-Datenabrufprozess zurückgegebenen Wert;
  • Local =
  • 5: Der Wert wurde lokal über set() oder update() gesetzt. value() enthält den manuell zugewiesenen Wert.
Diese Status helfen dabei, den Fortschritt der

Ressource zu verfolgen und ermöglichen eine bessere Handhabung asynchroner Vorgänge in Ihrer Anwendung.

hasValue( )-Funktion

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),
});
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Diese Methode ist reaktiv und ermöglicht es Ihnen, sie wie ein Signal zu konsumieren und zu verfolgen.

isLoading( )-Funktion

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")
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

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.


Ressourcenwert als WritableSignal

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 , ... }
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

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")
Nach dem Login kopieren

Hinweis:Das Wert-Signal der Ressourcen-API verwendet dasselbe Muster der neuen LinkedSignal-API, jedoch nicht es unter der Haube. ?

Convenience-Wrapper-Methoden

Um die Verwendung des value-Signals zu vereinfachen, stellt die Resource-API praktische Wrapper für set, update und asReadonly Methoden.

Die Methode

asReadonly 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 des

Werts: 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);
  }
}
Nach dem Login kopieren
Dadurch wird verhindert, dass Verbraucher den Wert ändern, wodurch das Risiko unbeabsichtigter Änderungen verringert und die Konsistenz bei der komplexen Datenverwaltung verbessert wird.


Laden Sie eine Ressource neu oder zerstören Sie sie

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.

reload( )-Funktion

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),
});
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

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.

destroy( )-Funktion

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")
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

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 . ?


rxResource( ) Funktion

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 , ... }
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

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.


Danke, dass du bisher gelesen hast?

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!

Quelle:dev.to
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage