我有一个基本的Angular组件,如下所示。从该组件中,我生成一个TestObj类型的对象数组,并在k个(0 <= k <= x.length)元素无法处理的情况下,使用相同的数组对的所有元素进行同步后调用,数组的其余部分未处理。
processing-component.component.ts
import { Component, OnInit } from "@angular/core";
import { FormBuilder, Form, FormGroup } from "@angular/forms";
import { Router } from "@angular/router";
import { processingService } from "./processing-component.service";
import { catchError, finalize, map } from "rxjs/operators";
import { concat } from "rxjs/observable/concat";
import { Observable, BehaviorSubject } from "rxjs";
export class TestObj {
processedFor:string;
isProcessingHappened: boolean ;
isProcessingSuccess: boolean;
constructor(isProcessingHappened,isProcessingSuccess) {
this.isProcessingHappened = isProcessingHappened;
this.isProcessingSuccess = isProcessingSuccess;
}
}
@Component({
selector: 'processing-component',
templateUrl: './processing-component.component.html',
styleUrls:['./processing-component.component.scss'],
providers: [ProcessingService]
})
export class ProcessingComponent {
constructor(private processingService: ProcessingService) { }
//some array generation logic to fetch arrayToProcess
public arrayToProcess: Array<TestObj>= [];
public displayedColumns: string[] = ['processedFor', 'isProcessingHappened', 'isProcessingSuccess']
public startBatchRun() {
const processes = this.arrayToProcess.map(details => this.processingService.runBatchExperiment(details).pipe(
map(() => {
this.isLoading.next(true);
details.isProcessingSuccess = true;
return this.arrayToProcess;
}),
catchError(() => {
this.isLoading.next(false);
details.isProcessingSuccess = false;
throw(false);
}),
finalize(() => {
this.isLoading.next(false);
details.isProcessingHappened = true;
}),
));
concat(...processes)
.map(() => this.isLoading = true)
.subscribe(res => {
})
}
}
我的服务如下
processing-component.service.ts
import { Injectable, Inject } from "@angular/core";
import { Http } from "@angular/http";
@Injectable()
export class ProcessingService {
constructor(@Inject('portfolioBaseUrl') private portfolioBaseUrl: string,
private http: Http) {}
processingUrl = this.portfolioBaseUrl + '/process/'
public runBatchExperiment(processingObj:TestObj ) {
return this.http.post(`${this.processingUrl}`,processingObj);
}
}
我的模板如下
processing-component.component.html
<button *ngIf = "arrayToProcess.length > 0" mat-raised-button (click) = "startBatchRun()" >Start Processing</button>
<div *ngIf = "arrayToProcess.length > 0" >
<mat-table [dataSource] = "arrayToProcess" >
<ng-container matColumnDef="processedFor">
<mat-header-cell *matHeaderCellDef> ID</mat-header-cell>
<mat-cell *matCellDef="let element"> {{element.processedFor }} </mat-cell> <!--add pipe here-->
</ng-container>
<ng-container matColumnDef="isProcessingHappened">
<mat-header-cell *matHeaderCellDef> Proceesing happened </mat-header-cell>
<mat-cell *matCellDef="let element">
<mat-icon *ngIf = "element.isProcessingHappened === true" >done</mat-icon>
<mat-icon *ngIf = "element.isProcessingHappened === false" >error_outline</mat-icon>
</mat-cell>
</ng-container>
<ng-container matColumnDef="isProcessingSuccess">
<mat-header-cell *matHeaderCellDef> Batch success </mat-header-cell>
<mat-cell *matCellDef="let element">
<mat-icon *ngIf = "element.isProcessingSuccess === true" >done</mat-icon>
<mat-icon *ngIf = "element.isProcessingSuccess === false" >error_outline</mat-icon>
</mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
</mat-table>
</div>
我还想做的是显示一个进度微调器,当调用后进入TestObj类型的对象时会显示该微调器,而当我们从后端收到特定对象的响应时它会隐藏。此进度微调器必须完全禁用UI屏幕。
我尝试使用拦截器服务来实现相同目的。这样做的问题是,拦截器显示整个前端进行的所有调用的进度微调器,而我试图实现的效果是做同样的事情,但仅针对ProcessingComponent进行的http调用。我尝试采用局部变量isLoading
,并在constructor
的ProcessingComponent
中将其设置为false,在执行startBatchRun
时,我将isLoading
设置为true,并在退出时将其设置为false startBatchRun
。有什么方法可以通过可观察的管道实现功能?
[您应该在数据表示例下,特别是在“ Table retrieving data through HTTP”示例下,查看Angular Material文档中描述的实现。
相关代码段:
displayedColumns: string[] = ['created', 'state', 'number', 'title'];
data: GithubIssue[] = [];
isLoadingResults = true;
...
ngAfterViewInit() {
...
merge(this.sort.sortChange, this.paginator.page)
.pipe(
startWith({}),
switchMap(() => {
this.isLoadingResults = true;
return this.exampleDatabase!.getRepoIssues(this.sort.active, this.sort.direction, this.paginator.pageIndex);
}),
map(data => {
...
this.isLoadingResults = false;
...
return data.items;
}),
catchError(() => {
...
return observableOf([]);
})
).subscribe(data => this.data = data);
}
这样,您只需要一个本地布尔变量,并根据变量的状态隐藏/显示微调框。
[如果您希望对请求进行反跳操作(这样就不会每次都出现,即使对于最后一个100ms
的请求也是如此),您可以在timer
中添加一个switchMap()
,如下所示:] >
...
switchMap(() => {
const result$ = this.exampleDatabase!.getRepoIssues(this.sort.active, this.sort.direction, this.paginator.pageIndex);
timer(100).pipe(takeUntil(result$)).subscribe(t => this.isLoadingResults = true);
}),
...