如何使用Http对Angular 2中的特定组件正确使用进度微调器?

问题描述 投票:0回答:1

我有一个基本的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,并在constructorProcessingComponent中将其设置为false,在执行startBatchRun时,我将isLoading设置为true,并在退出时将其设置为false startBatchRun。有什么方法可以通过可观察的管道实现功能?

angular typescript angular-material synchronous angular-http
1个回答
0
投票

[您应该在数据表示例下,特别是在“ 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);
 }),

...
© www.soinside.com 2019 - 2024. All rights reserved.