iT邦幫忙

0

在 Angular Resource API 中串流多個回應

  • 分享至 

  • xImage
  •  

當 Resource API 首次問世時,resource 函數傳回一個 promise,而 rxResource 函數只傳回 Observable 的第一個值。在 rxResource 函數中尤其明顯,當

rxResource({
  request : this.num,
  loader: ({ request: n }) => timer(0, 1000).pipe(take(n))
})

發出一個整數並且結束,而不是 n 個整數。

幸運的是,資源 API 將支援串流傳輸,其中函數可以在 Angular 19.2.0 中傳回多個回應。

rxResource 函數的選項保持不變,但 resource 函數有一個新的選項, stream, 來支援串流。

在這篇文章中,我將示範如何使用 rxResourceresource 函數來串流傳輸表格行。

自訂 makeARow RxJS 運算子

function makeRows(numRows: number, numElementsPerRow: number) {
 return function (source: Observable<number>) {
   return source.pipe(
     tap((i) => console.log('timer called', i)),
     map((num) => Array(numElementsPerRow).fill(0).map((_, index) => (num * numElementsPerRow + index) + 1)),
     take(numRows),
   )
 }
}

makeRows 自訂運算子會填入數字數組,並在填入指定數量的行後取消訂閱。

使用 rxResource 函數串流數據

@let rxResourceTitle = 'Aggregate table rows with rxResource stream';
<ng-container [ngTemplateOutlet]="table" [ngTemplateOutletContext]="{ $implicit: tableDataRxResource, title: rxResourceTitle }"/>

<ng-template #table let-tableResource let-title="title">
 <p>{{ title }}</p>
 @for (row of tableResource.value(); track $index) {
   <div>
   @for (data of row; track data; let last=$last) {
     @let delimiter = last ? '' : ', ';
     <span>{{ `${data}${delimiter}` }}</span>
   }
   </div>
 }
</ng-template>

在 HTML 範本中,我建立了一個 NgTemplate 來顯示表格行和靜態標題。 在 ng-container 元素中,我將模板變數 table 指派給 ngTemplateOutlet 輸入。此外,我將靜態標題和資源值指派給 ngTemplateOutletContext 輸入。

@Component({
 selector: 'app-root',
 imports: [NgTemplateOutlet],
 templateUrl: 'main.component.html',
 changeDetection: ChangeDetectionStrategy.OnPush,
})
export class App {
 rowSub = new Subject<number[]>();
 table$ = this.rowSub.pipe(
   scan((acc, values) => ([...acc, values]), [] as number[][]),
 );

  tableDataRxResource = rxResource({
   loader: () => this.table$,
 });

 constructor() {
   timer(0, 1000)
     .pipe(makeRows(10, 10))
     .subscribe({
       next: (array) => this.rowSub.next(array)
     });
 }
}

rowSub 是一個發出數字數組的 Subject。 當 rowSub 發出新陣列時,table$ Observable 使用 scan RxJS 運算子將其附加到巢狀陣列中。

tableDataRxResource 資源由 rxResource 函數建立。此資源有一個 loader,可在表格行到達時進行串流傳輸。

RxJS timer 在建構函式中每秒產生一個新行,並在第十次後停止。 當 Observable 訂閱時,結果會回饋給 rowSub Subject。

使用 resource 函數串流數據

<ng-container [ngTemplateOutlet]="table" [ngTemplateOutletContext]="{ $implicit: tableDataResource, title: 'Aggregate table rows with resource stream' }"/>

<ng-template #table let-tableResource let-title="title">
 <p>{{ title }}</p>
 @for (row of tableResource.value(); track $index) {
   <div>
   @for (data of row; track data; let last=$last) {
     @let delimiter = last ? '' : ', ';
     <span>{{ `${data}${delimiter}` }}</span>
   }
   </div>
 }
</ng-template>

ng-container 使用相同的模板但具有不同的 resource 和靜態圖塊。

table = signal<{ value: number[][] }>({ value: [] });

The table signal holds an object with a value property. The property stores a nested number array.

tableDataResource = resource({
   stream: async () => this.table,
});

tableDataResource 資源使用 resource 函數來串流傳輸表格行。 stream 選項是新的,並且需要一個返回訊號 (signal) 的非同步函數 (async function)。

@Component({
   ...
})
export class App {
 table = signal<{ value: number[][] }>({ value: [] });

 tableDataResource = resource({
   stream: async () => this.table,
 });

 constructor() {
   timer(0, 1500)
     .pipe(makeRows(10, 10))
     .subscribe({
       next: (array) => 
         this.table.update(({ value }) => ({ value: [...value, array] }))
     }); 
 }
}

RxJS timer 訂閱並將新的數字數組附加到 table 訊號。

resource 函數 與 rxResource 函數演示相同的結果;每秒新增一行。

參考:


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言