首頁 web前端 js教程 Angular resource() 和 rxResource() API:您需要了解的內容

Angular resource() 和 rxResource() API:您需要了解的內容

Jan 04, 2025 am 06:52 AM

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

幾週前發布的Angular v19 標誌著框架內訊號革命的一個重要里程碑,輸入模型輸出訊號查詢 API現已正式升級為穩定版。

但這還不是全部!這個主要版本也引進了旨在進一步推進訊號革命的強大新工具:新的資源API

顧名思義,這個新的資源 API 旨在透過充分利用訊號的力量來簡化載入非同步資源

重要提示:在撰寫本文時,新的資源 API 仍處於實驗階段。這意味著它在變得穩定之前可能會發生變化,因此使用它需要您自擔風險。 ?

讓我們深入了解它的工作原理以及它如何簡化非同步資源的處理!


資源 API

大多數訊號 API 都是同步的,但在實際應用中,處理非同步資源至關重要,例如從伺服器取得資料或即時管理使用者互動。

這就是新的資源 API 發揮作用的地方。

使用資源,您可以輕鬆地透過訊號消耗非同步資源,從而輕鬆管理資料擷取、處理載入狀態,並在相關訊號參數變更時觸發新的擷取。

資源( ) 函數

建立資源更簡單的方法是使用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 配置物件作為輸入,允許您指定以下屬性:

  • 請求:一個反應函數,用於確定用於執行對非同步資源的請求的參數;
  • loader:一個載入函數,傳回資源值的 Promise,可以選擇基於提供的 request 參數。這是 ResourceOptions; 唯一的 必需的
  • 屬性
  • equal:相等函數,用於比較loader的回傳值;
  • injector:覆寫 Resource 實例使用的 Injector,以便在父元件或服務被銷毀時銷毀自身。

借助這些配置,我們可以輕鬆定義非同步依賴項,它將始終被有效使用並保持最新。

資源生命週期

一旦建立了資源,就會執行loader函數,然後產生的非同步請求開始:

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),
});
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製

每當有訊號表示request 函數依賴於變更時,request 函數會再次運行,如果傳回新參數,則會觸發loader 函數取得更新後的資源值:

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")
登入後複製
登入後複製
登入後複製

如果沒有提供request 函數,則loader 函數將只運行一次,除非使用reload重新載入Resource方法(更多下文)。

最後,一旦父元件或服務被銷毀,資源也會被銷毀,除非提供了特定的注入器。

在這種情況下,資源將保持活動狀態,並且僅當提供的注入器本身被銷毀時才會被銷毀。

使用 abortSignal 中止請求

為了優化資料獲取,如果 request() 計算發生變化而先前的值仍在加載,資源 可以中止未完成的請求。

為了管理此問題,loader() 函數提供了 abortSignal,您可以將其傳遞給正在進行的請求,例如 fetch。此請求監聽 abortSignal 並在觸發時取消操作,確保高效的資源管理並防止不必要的網路請求:

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 , ... }
登入後複製
登入後複製
登入後複製

基於此,建議主要針對 GET 請求使用 Resource API,因為它們通常可以安全地取消而不會引起問題。

對於 POSTUPDATE 請求,取消可能會導致意想不到的副作用,例如不完整的資料提交或更新。但是,如果您需要針對這些類型的請求提供類似的功能,則可以使用 effect() 方法來安全地管理操作。


如何使用資源

資源 API 為其狀態提供了多個訊號屬性,您可以直接在元件或服務中輕鬆使用它們:

  • :包含資源的目前值,如果沒有可用值,則包含未定義。作為WritableSignal,可以手動更新;
  • 狀態:包含資源的當前狀態,指示資源正在做什麼以及可以從其中得到什麼;
  • 錯誤:如果處於錯誤狀態,則包含資源載入期間引發的最新錯誤;
  • isLoading:指示資源是否正在載入新值或重新載入現有值。

以下是如何在元件中使用資源的範例:

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),
});
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製

在此範例中,Resource 用於根據 id 訊號​​的值從 API 取得數據,該訊號可以透過點擊按鈕來遞增。

每當使用者點擊按鈕時,id 訊號​​值都會發生變化,從而觸發 loader 函數從遠端 API 取得新項目。

由於 Resource API 公開的訊號屬性,UI 會自動使用所取得的資料進行更新。


檢查資源的狀態

如前所述,狀態訊號提供有關資源在任何給定時刻的當前狀態的資訊。

status 訊號​​的可能值由 ResourceStatus 列舉定義。以下是這些狀態及其對應值的摘要:

  • 空閒 = 0資源沒有有效要求,不會執行任何載入。 value()未定義;
  • Error = 1:載入失敗並出現錯誤。 value()未定義;
  • 正在載入 = 2:由於請求發生更改,資源目前正在載入新值。 value()未定義;
  • 正在重新載入 = 3:資源目前正在為相同請求重新載入新值。 value()會繼續傳回先前取得的值,直到重新載入作業完成;
  • 已解決=4:載入完成。 value() 包含載入器資料取得程序傳回的值;
  • Local = 5:該值是透過 set()update() 在本地設定的。 value() 包含手動指派的值。

這些狀態有助於追蹤資源的進度,並有助於更好地處理應用程式中的非同步操作。

hasValue() 函數

鑑於這些狀態的複雜性,資源 API 提供了 hasValue() 方法,該方法根據當前狀態傳回一個布林值。

這確保了有關資源狀態的準確信息,提供了一種更可靠的方法來處理非同步操作,而不依賴於值,該值在某些狀態下可能是未定義

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),
});
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製

此方法是響應式的,允許您像訊號一樣使用和追蹤它。

isLoading()函數

Resource API 也提供了 isLoading 訊號​​,該訊號會傳回資源目前是否處於 LoadingReloading 狀態:

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")
登入後複製
登入後複製
登入後複製

由於 isLoading 是一個計算訊號,因此可以對其進行反應式跟踪,從而允許您使用訊號 API 即時監控載入狀態。


作為 WritableSignal 的資源值

Resource提供的值訊號是一個WritableSignal,它允許您使用set()update()手動更新它) 功能:

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 , ... }
登入後複製
登入後複製
登入後複製

注意:如您所見,手動更新訊號的也會將狀態設為5,這表示「本地”,表示該值是本地設定的。

手動設定的值將持續存在,直到設定新值或執行新請求,這將使用新值覆寫它:

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")
登入後複製

注意: Resource APIvalue 訊號​​使用與新的LinkedSignal API 相同的模式,但不使用它在引擎蓋下。 ?

便利包裝方法

為了簡化value 訊號​​的使用,Resource API 為setupdateupdateasReadonly 方法。

asReadonly 方法特別有用,因為它會傳回 value 訊號​​的唯讀實例,僅允許讀取存取並防止任何意外修改。

您可以使用此方法透過匯出 value:
的唯讀實例來建立管理和追蹤資源值變更的服務

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);
  }
}
登入後複製

這將防止消費者修改值,降低意外變更的風險,並提高複雜資料管理的一致性。


重新載入或銷毀資源

使用非同步資源時,您可能會遇到需要刷新資料或銷毀資源的情況。

為了處理這些場景,資源 API 提供了兩種專用方法,為管理這些操作提供有效的解決方案。

重新載入()函數

reload() 方法指示 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),
});
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製

如果成功啟動重新載入,reload() 方法將傳回 true

如果無法執行重新加載,無論是因為沒有必要,例如當狀態已正在加載正在重新加載,或不支持,例如當狀態為時空閒,該方法回傳false.

銷毀()函數

destroy() 方法手動銷毀Resource,銷毀任何用於追蹤請求更改的effect(),取消任何待處理的請求,並設定狀態為空閒,同時將數值重設為未定義:

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")
登入後複製
登入後複製
登入後複製

資源被銷毀後,它將不再回應請求更改或reload()操作。

注意:此時,雖然value訊號仍然可寫,但Resource將失去其預期目的,不再發揮其功能,變得無用。 ?


rxResource( ) 函數

與迄今為止引入的幾乎所有基於訊號的 API 一樣,資源 API 還提供了一個互通性實用程序,用於與 RxJS 無縫整合。

您可以使用rxResource() 方法來建立基於Promise 的Resource,而不是使用resource() 方法來使用可觀察

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 , ... }
登入後複製
登入後複製
登入後複製

注意: rxResource() 方法實際上是由 rxjs-interop 套件公開的。

loader() 函數產生的 Observable 將只考慮第一個發射值,忽略後續發射。


感謝您閱讀到目前為止?

感謝大家在這個美好的2024年跟隨我。 ??

這是充滿挑戰的一年,但也非常有收穫。我對 2025 年有宏偉的計劃,我迫不及待地想開始實施它們。 ?

我想得到您的回饋,所以請留下評論按讚追蹤。 ?

然後,如果您真的喜歡它,請在您的社區、技術兄弟和任何您想要的人中分享它。別忘了在 LinkedIn 上追蹤我。 ??

以上是Angular resource() 和 rxResource() API:您需要了解的內容的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1657
14
CakePHP 教程
1415
52
Laravel 教程
1309
25
PHP教程
1257
29
C# 教程
1229
24
神秘的JavaScript:它的作用以及為什麼重要 神秘的JavaScript:它的作用以及為什麼重要 Apr 09, 2025 am 12:07 AM

JavaScript是現代Web開發的基石,它的主要功能包括事件驅動編程、動態內容生成和異步編程。 1)事件驅動編程允許網頁根據用戶操作動態變化。 2)動態內容生成使得頁面內容可以根據條件調整。 3)異步編程確保用戶界面不被阻塞。 JavaScript廣泛應用於網頁交互、單頁面應用和服務器端開發,極大地提升了用戶體驗和跨平台開發的靈活性。

JavaScript的演變:當前的趨勢和未來前景 JavaScript的演變:當前的趨勢和未來前景 Apr 10, 2025 am 09:33 AM

JavaScript的最新趨勢包括TypeScript的崛起、現代框架和庫的流行以及WebAssembly的應用。未來前景涵蓋更強大的類型系統、服務器端JavaScript的發展、人工智能和機器學習的擴展以及物聯網和邊緣計算的潛力。

JavaScript引擎:比較實施 JavaScript引擎:比較實施 Apr 13, 2025 am 12:05 AM

不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

JavaScript:探索網絡語言的多功能性 JavaScript:探索網絡語言的多功能性 Apr 11, 2025 am 12:01 AM

JavaScript是現代Web開發的核心語言,因其多樣性和靈活性而廣泛應用。 1)前端開發:通過DOM操作和現代框架(如React、Vue.js、Angular)構建動態網頁和單頁面應用。 2)服務器端開發:Node.js利用非阻塞I/O模型處理高並發和實時應用。 3)移動和桌面應用開發:通過ReactNative和Electron實現跨平台開發,提高開發效率。

Python vs. JavaScript:學習曲線和易用性 Python vs. JavaScript:學習曲線和易用性 Apr 16, 2025 am 12:12 AM

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

如何使用Next.js(前端集成)構建多租戶SaaS應用程序 如何使用Next.js(前端集成)構建多租戶SaaS應用程序 Apr 11, 2025 am 08:22 AM

本文展示了與許可證確保的後端的前端集成,並使用Next.js構建功能性Edtech SaaS應用程序。 前端獲取用戶權限以控制UI的可見性並確保API要求遵守角色庫

從C/C到JavaScript:所有工作方式 從C/C到JavaScript:所有工作方式 Apr 14, 2025 am 12:05 AM

從C/C 轉向JavaScript需要適應動態類型、垃圾回收和異步編程等特點。 1)C/C 是靜態類型語言,需手動管理內存,而JavaScript是動態類型,垃圾回收自動處理。 2)C/C 需編譯成機器碼,JavaScript則為解釋型語言。 3)JavaScript引入閉包、原型鍊和Promise等概念,增強了靈活性和異步編程能力。

如何安裝JavaScript? 如何安裝JavaScript? Apr 05, 2025 am 12:16 AM

JavaScript不需要安裝,因為它已內置於現代瀏覽器中。你只需文本編輯器和瀏覽器即可開始使用。 1)在瀏覽器環境中,通過標籤嵌入HTML文件中運行。 2)在Node.js環境中,下載並安裝Node.js後,通過命令行運行JavaScript文件。

See all articles