Angular 角度类型脚本订阅嵌套对象订阅

Angular 角度类型脚本订阅嵌套对象订阅,angular,typescript,Angular,Typescript,我有一个丑陋的嵌套对象,其中有一个子对象需要http post订阅,这很有效。嵌套对象和父对象的上游都是列表对象本身。我需要做的是,这个孩子的父母需要做一个汇总计算 我的问题:能否/如何订阅同一对象中的嵌套订阅 以下是我的原始http模型: export interface GatewayExtractRun { clientName?: string; extractruns?: Array<GatewayExtractExtractRuns>; } expor

我有一个丑陋的嵌套对象,其中有一个子对象需要http post订阅,这很有效。嵌套对象和父对象的上游都是列表对象本身。我需要做的是,这个孩子的父母需要做一个汇总计算

我的问题:能否/如何订阅同一对象中的嵌套订阅

以下是我的原始http模型:

export interface GatewayExtractRun { 
    clientName?: string;
    extractruns?: Array<GatewayExtractExtractRuns>;
}

export interface GatewayExtractExtractRuns { 
    extractName?: string;
    runs?: Array<GatewayExtractRuns>;
}

export interface GatewayExtractRuns { 
    queryExecutionId?: string;
    runTime?: string;
    extractSqlDefinition?: string;
    isIncremental?: string;
}
然后,流程从树开始(按其列出的顺序)。我感到困惑的是,我需要的数据在订阅中:

private convertGatewayExtractRunsToViewModel( 
    childExtract: GatewayExtractRuns[],
): ExtractRunViewModel[] {
    let returnModel: ExtractRunViewModel[] = [];
    childExtract.forEach((element) => {
        const singleItemReturnModel: ExtractRunViewModel = this.transformGatewayExtractRunsToViewModel(
            element,
        );
        // true starting point of conversion, retrieve the batch status
        this.trackerService
            .putBatchStatusByFile(element.queryExecutionId)
            .subscribe((response) => {
                // 2 part, we need to update the child and the parent summary data for job status's
                singleItemReturnModel.endstatus = response.jobStatus;
                returnModel.push(singleItemReturnModel);
            },
                (err) => {
                    console.error(err);
                    this.clientConfiguration = undefined;
                });
    });
    return returnModel;
}
它需要其父级计算ExtractRunsViewModel的和

我试图将客户端和提取名称的传递传递给订阅,然后在订阅中循环以更新其父级。但这导致了不一致的结果

public clientConfigurationObs: Observable<GatewayExtractRun>;
public clientConfiguration: GatewayExtractRun;

public extractRunsViewModel: ExtractsViewModel;

constructor(
    private readonly service1: ConfigurationService,
    private readonly trackerService: TrackerService,
) { }

private setupClientConfiguration(): void {
    this.clientConfigurationObs = this.service1.getClientExtractsRunStats(
        this.clientName,
    );

    this.handleClientConfiguration();
}

private handleClientConfiguration(): void {
    this.clientConfigurationObs.subscribe(
        (gatewayextractrun) => {
            this.clientConfiguration = gatewayextractrun;
            if (gatewayextractrun.clientName != null) {
                this.extractRunsViewModel = this.convertGatewayExtractRunToViewModel(
                    gatewayextractrun
                );
            }
        },
        (err) => {
            console.error(err);
            this.clientConfiguration = undefined;
        },
    );

    console.log('extractsRunsViewModel complete');
    console.log(this.extractRunsViewModel);
}

private convertGatewayExtractRunToViewModel(
    rootExtract: GatewayExtractRun,
): ExtractsViewModel {
    const returnModel: ExtractsViewModel = {
        clientName: rootExtract.clientName,
        extractRuns: this.convertGatewayExtractExtractRunsViewModel(
            rootExtract.extractruns,
        ),
    };
    return returnModel;
}

private convertGatewayExtractExtractRunsViewModel(
    parentExtract: GatewayExtractExtractRuns[],
): ExtractRunsViewModel[] {
    // tslint:disable-next-line:prefer-const
    let returnModel: ExtractRunsViewModel[] = [];
    parentExtract.forEach((element) => {
        const singleItemReturnModel: ExtractRunsViewModel = this.transformGatewayExtractExtractRunsToViewModel(
            element,
        );
        returnModel.push(singleItemReturnModel);
    });
    return returnModel;
}

/**
 * Maps a  Gateway extract run from a GatewayExtractRuns to a ExtractViewModel by adding a end extract status.
 * @param parentExtract a single extract's run to be transformed into a temp view model with an 'UNKNOWN' end status.
 */
private transformGatewayExtractExtractRunsToViewModel(
    parentExtract: GatewayExtractExtractRuns,
): ExtractRunsViewModel {
    let returnModel: ExtractRunsViewModel = {
        extractName: parentExtract.extractName,
        runs: this.convertGatewayExtractRunsToViewModel(parentExtract.runs),
        statusGreenCount: 0,
        statusInProcessCount: 0,
        statusRedCount: 0,
        statusUnknownCount: 0,
    };

    return returnModel;
}

/**
 * Converts a list of GatewayExtractRuns, tied to parent extract name, into a list of ExtractRunViewModels
 * which have a extract end extract status column. Also at this time the parent extract will recieve
 * updated summary status data for the sucessful/failed/unknown/in process extracts.
 * @param childExtract a single extract's run to be transformed into a temp view model with an 'UNKNOWN' end status.
 */
private convertGatewayExtractRunsToViewModel( 
    childExtract: GatewayExtractRuns[],
): ExtractRunViewModel[] {
    let returnModel: ExtractRunViewModel[] = [];
    childExtract.forEach((element) => {
        const singleItemReturnModel: ExtractRunViewModel = this.transformGatewayExtractRunsToViewModel(
            element,
        );
        // true starting point of conversion, retrieve the batch status
        this.trackerService
            .putBatchStatusByFile(element.queryExecutionId)
            .subscribe((response) => {
                // 2 part, we need to update the child and the parent summary data for job status's
                singleItemReturnModel.endstatus = response.jobStatus;
                returnModel.push(singleItemReturnModel);

            // ***************************************
            // ALSO UPDATE PARENT HERE IF POSSIBLE
            // parentExtract = this.updateQueryStatusCounts(parentExtract, singleItemReturnModel.endstatus);
            // ***************************************

            },
                (err) => {
                    console.error(err);
                    this.clientConfiguration = undefined;
                });
    });
    return returnModel;
}

/**
 * Maps a  Gateway extract run from a GatewayExtractRuns to a ExtractViewModel by adding a end extract status.
 * @param childExtract a single extract's run to be transformed into a temp view model with an 'UNKNOWN' end status.
 */
private transformGatewayExtractRunsToViewModel(
    childExtract: GatewayExtractRuns,
): ExtractRunViewModel {
    const returnModel: ExtractRunViewModel = {
        queryExecutionId: childExtract.queryExecutionId,
        runTime: childExtract.runTime,
        extractSqlDefinition: childExtract.extractSqlDefinition,
        isIncremental: childExtract.isIncremental,
        endstatus: 'UNKNOWN',
    };
    return returnModel;
}

private updateQueryStatusCounts(
    jobstatus: string,
    modelToUpdate: ExtractRunsViewModel,
): ExtractRunsViewModel {
    switch (this.determineJobStatus(jobstatus)) {
        case 2: {
            modelToUpdate.statusGreenCount =
                modelToUpdate.statusGreenCount + 1;
            break;
        }
        case 1: {
            modelToUpdate.statusInProcessCount =
                modelToUpdate.statusInProcessCount + 1;
            break;
        }
        case 0: {
            modelToUpdate.statusUnknownCount =
                modelToUpdate.statusUnknownCount + 1;
            break;
        }
        case -1: {
            modelToUpdate.statusRedCount = modelToUpdate.statusRedCount + 1;
            break;
        }
        default: {
            break;
        }
    }
    return modelToUpdate;
}

private determineJobStatus(jobstatus: string) {
    if (jobstatus === 'SUCCEEDED') {
        return 2;
    } else if (jobstatus === 'FAILED') {
        return -1;
    } else if (
        jobstatus === 'PENDING' ||
        jobstatus === 'RUNNABLE' ||
        jobstatus === 'RUNNING' ||
        jobstatus === 'STARTING' ||
        jobstatus === 'SUBMITTED'
    ) {
        return 1;
    } else {
        return 0;
    }
}
private setupClientConfiguration(): void {
    this.clientConfigurationObs = this.service1.getClientExtractsRunStats(
        this.clientName,
    );

    this.handleClientConfiguration();
}
private convertGatewayExtractRunsToViewModel( 
    childExtract: GatewayExtractRuns[],
): ExtractRunViewModel[] {
    let returnModel: ExtractRunViewModel[] = [];
    childExtract.forEach((element) => {
        const singleItemReturnModel: ExtractRunViewModel = this.transformGatewayExtractRunsToViewModel(
            element,
        );
        // true starting point of conversion, retrieve the batch status
        this.trackerService
            .putBatchStatusByFile(element.queryExecutionId)
            .subscribe((response) => {
                // 2 part, we need to update the child and the parent summary data for job status's
                singleItemReturnModel.endstatus = response.jobStatus;
                returnModel.push(singleItemReturnModel);
            },
                (err) => {
                    console.error(err);
                    this.clientConfiguration = undefined;
                });
    });
    return returnModel;
}