问题描述
我正在使用“ ngx-spinner”:“ 8.1.0”,在从服务器获取数据的方法的tap()中显示了Spinner。Spinner显示了,但是当试图在finalize()上隐藏它时却没有被隐藏完全没有有什么提示可能是问题所在吗?接收到来自服务器的数据并将其正确显示在视图上。
// component.ts
import logging
import pandas as pd
import argparse
import datetime
#================ Apache beam ======================
import apache_beam as beam
from apache_beam.options.pipeline_options import PipelineOptions
from apache_beam.options.pipeline_options import StandardOptions
from apache_beam.options.pipeline_options import GoogleCloudOptions
from apache_beam.options.pipeline_options import SetupOptions
from apache_beam.options.pipeline_options import WorkerOptions
from apache_beam.options.pipeline_options import DebugOptions
from apache_beam.io import ReadFromText
from apache_beam.io import WritetoText
from apache_beam.io import fileio
import io
#======================
PROJECT_ID = 'my-project'
GCS_STAGING_LOCATION = 'gs://my-bucket//gcs_staging_location/'
GCS_TMP_LOCATION = 'gs://my-bucket/gcs_tmp_location/'
#======================================
# https://cloud.google.com/dataflow/docs/guides/templates/creating-templates#valueprovider
class FileIterator(beam.DoFn):
def __init__(self,files_bucket):
self.files_bucket = files_bucket
def process(self,element):
files = pd.read_csv(str(element),header=None).values[0].tolist()
bucket = self.files_bucket.get()
files = [str(bucket) + '/' + file for file in files]
logging.info('Files list is: {}'.format(files))
return files
#=========================================================
# https://stackoverflow.com/questions/58240058/ways-of-using-value-provider-parameter-in-python-apache-beam
class OutputValueProviderFn(beam.DoFn):
def __init__(self,vp):
self.vp = vp
def process(self,unused_elm):
yield self.vp.get()
#=========================================================
class RuntimeOptions(PipelineOptions):
@classmethod
def _add_argparse_args(cls,parser):
parser.add_value_provider_argument(
'--files_bucket',help='Bucket where the raw files are',type=str)
parser.add_value_provider_argument(
'--complete_batch',help='Text file with filenames in it location',type=str)
parser.add_value_provider_argument(
'--comp_table',required=False,help='BQ table to write to (dataset.table)',type=str)
#=========================================================
def run():
#====================================
# Todo PUT AS ParaMETERS
#====================================
dt_Now = datetime.datetime.Now().strftime('%Y%m%d')
job_name = 'dataflow-test-{}'.format(dt_Now)
pipeline_options_batch = PipelineOptions()
runtime_options = pipeline_options_batch.view_as(RuntimeOptions)
setup_options = pipeline_options_batch.view_as(SetupOptions)
setup_options.setup_file = './setup.py'
google_cloud_options = pipeline_options_batch.view_as(GoogleCloudOptions)
google_cloud_options.project = PROJECT_ID
google_cloud_options.staging_location = GCS_STAGING_LOCATION
google_cloud_options.temp_location = GCS_TMP_LOCATION
pipeline_options_batch.view_as(StandardOptions).runner = 'DataflowRunner'
pipeline_options_batch.view_as(WorkerOptions).autoscaling_algorithm = 'THROUGHPUT_BASED'
pipeline_options_batch.view_as(WorkerOptions).max_num_workers = 10
pipeline_options_batch.view_as(SetupOptions).save_main_session = True
pipeline_options_batch.view_as(DebugOptions).experiments = ['use_beam_bq_sink']
with beam.Pipeline(options=pipeline_options_batch) as pipeline_2:
try:
final_data = (
pipeline_2
|'Create empty PCollection' >> beam.Create([None])
|'Get accepted batch file'>> beam.ParDo(OutputValueProviderFn(runtime_options.complete_batch))
# |'Read all filenames into a list'>> beam.ParDo(FileIterator(runtime_options.files_bucket))
)
except Exception as exception:
logging.error(exception)
pass
#=========================================================
if __name__ == "__main__":
run()
service.ts
ngAfterViewInit() {
this.subscriptions.add(
this.organizationsService.organizations$
.pipe(
tap(() => {
this.spinnerService.showLoader();
}),finalize(() => {
this.spinnerService.hideLoader();
}),takeuntil(this.destroySubject))
.subscribe(response => {
console.log('OUTPUT: OrganizationsListComponent -> ngAfterViewInit -> response',response);
this.cachedFacts = this.cachedFacts.concat(response);
if (!this.searchService.search.value.length) {
this.dataSource.data = this.cachedFacts as IOrganizations[];
this.dataSource.sort = this.sort;
} else {
this.dataSource.data = response as IOrganizations[];
this.cachedFacts = [];
}
this.filterSelectObj.filter((o) => {
o.options = this.getFilterObject(this.dataSource.data,o.columnProp);
});
},(error) => {
this.errorService.handleError(error);
})
);
}
spinner.service.ts
this.organizations$ = combineLatest([this.pageSubject,this.searchService.search]).pipe(
tap(([page,searchTerm]) => { console.log('search and page number',page,searchTerm); }),switchMap(([page,searchTerm]) => {
let params: HttpParams;
if (!searchTerm.length) {
params = new HttpParams()
.set('_page',page.toString());
} else {
params = new HttpParams()
.set('q',searchTerm);
}
const apiUrl = this.http.get<IOrganizations[]>(`${this.apiUrl}`,{ observe: 'response',params });
return apiUrl.pipe(
map((result) => {
const totalCount = result.headers.get('x-total-count');
this.totalOrganizationsCount.next(totalCount);
this.cachedOrganizationsList.next(result.body);
return result.body;
})
);
})
);
spinner.module.ts
@Injectable()
export class SpinnerService {
constructor(private spinnerService: NgxSpinnerService) { }
public showLoaderSubject = new BehaviorSubject<boolean>(false);
showLoader() {
this.showLoaderSubject.next(true);
this.spinnerService.show();
}
hideLoader() {
this.showLoaderSubject.next(false);
this.spinnerService.hide();
}
}
感谢任何提示
解决方法
RxJS finalize
运算符仅在可观察到的源代码完成或出现错误时才被触发。看到您的可观察对象organizations$
拥有combineLatest
函数中的可观察对象,它可能尚未完成。因此,您可以将微调器隐藏在订阅中,而不是使用finalize
。
尝试以下
ngAfterViewInit() {
this.subscriptions.add(
this.organizationsService.organizations$.pipe(
tap(() => this.spinnerService.showLoader()),// <-- no `finalize` here
takeUntil(this.destroySubject)
).subscribe(response => {
console.log('OUTPUT: OrganizationsListComponent -> ngAfterViewInit -> response',response);
this.cachedFacts = this.cachedFacts.concat(response);
if (!this.searchService.search.value.length) {
this.dataSource.data = this.cachedFacts as IOrganizations[];
this.dataSource.sort = this.sort;
} else {
this.dataSource.data = response as IOrganizations[];
this.cachedFacts = [];
}
this.filterSelectObj.filter((o) => {
o.options = this.getFilterObject(this.dataSource.data,o.columnProp);
});
this.spinnerService.hideLoader(); // <-- hide the spinner here
},(error) => {
this.errorService.handleError(error);
})
);
}