У меня проблема с индикатором выполнения. Я использую для этого нг- bootstrap модуль.
У меня есть несколько вариантов в раскрывающемся списке, и я хотел бы иметь следующее поведение: - Я могу запускать / останавливать индикатор выполнения для каждого параметра из выпадающего списка отдельно, - Когда я изменяю параметр на другой параметр и возвращаюсь -> подсчет будет в фоновом режиме.
Ниже решение работало отлично. Но, как и в IT, sth был изменен, и я не увидел ошибку.
Сервисный файл:
@Injectable()
export class TimerService {
constructor(private httpClient: HttpClient) {
}
private timer = [];
private timerStarted: boolean [] = [false];
private stopTimer$: Subject<any> [] = [];
startTimer(duration: number, indexDropdown: number) {
this.stopTimer$[indexDropdown] = new Subject();
this.timerStarted[indexDropdown] = false;
this.timer[indexDropdown] = interval(duration).pipe(take(1000), takeUntil(this.stopTimer$[indexDropdown]), share());
this.timer[indexDropdown].pipe(
tap(() => this.timerStarted[indexDropdown] = true),
finalize(() => this.timerStarted[indexDropdown] = false)
).subscribe();
}
getTimer(indexDropdown: number) {
return this.timer[indexDropdown];
}
getTimerStarted(indexDropdown: number) {
return this.timerStarted[indexDropdown];
}
stopTimer(indexDropdown: number) {
this.stopTimer$[indexDropdown].next();
}
}
И файл компонента:
export class TimerComponent implements OnInit, OnDestroy, OnChanges {
@Input() optionDropdownArray: string[];
isLoading: boolean;
progress: number [] = [0];
private destroy$: Subject<boolean>[] = [];
private loadingIndexSub: Subscription;
selectedIndex = 0;
timerObserver$ = [];
constructor(
private timerService: timerService,
private timerStore$: Store<TimerStatus>,
private indexService: TimerService,
private config: NgbProgressbarConfig) {
config.max = 1000;
config.striped = false;
config.animated = false;
config.type = 'success';
config.height = '3.5em';
}
ngOnChanges(): void {
this.loadingIndexSub = this.indexService.gettingIndexSelected.subscribe(getIndex => {
this.selectedIndex = getIndex;
this.isLoading = false;
this.checkProgressSubscriptions();
if (this.timerService.getTimerStarted(getIndex)) {
this.destroy$[this.selectedIndex] = new Subject<false>();
this.progress[getIndex] = this.timerService.getTimer(getIndex).pipe(take(1)).subscribe();
this.checkProgressSubscriptions();
this.subscribeToStartedTimer(getIndex);
this.isLoading = true;
}
});
}
ngOnInit() {
this.loadingIndexSub = this.indexService.gettingIndexSelected.subscribe(getIndex => {
this.selectedIndex = getIndex;
});
}
private startProcessing() {
this.destroy$[this.selectedIndex] = new Subject<boolean>();
this.isLoading = true;
this.progress[this.selectedIndex] = 0;
this.timerStore$
.select(selectDurationActiveWorkStep, {timerSelectorProps: this.selectedIndex}).subscribe(timeArray => {
this.timerService.startTimer(timeArray.activeTaskDuration, this.selectedIndex);
this.subscribeToStartedTimer(this.selectedIndex);
});
}
private stopProcessing() {
this.isLoading = false;
if (this.destroy$[this.selectedIndex] != undefined) {
this.destroy$[this.selectedIndex].next(true);
}
this.timerService.stopTimer(this.selectedIndex);
}
private subscribeToStartedTimer(dropdownIndexId: number) {
this.timerObserver$[dropdownIndexId] = this.timerService.getTimer(dropdownIndexId).pipe(
takeUntil(this.destroy$[dropdownIndexId])
).subscribe((val => {
this.progress[dropdownIndexId] = val + 1;
}));
}
private checkProgressSubscriptions() {
for (let i = 0; i < this.optionDropdownArray.length; i++) {
if (this.timerObserver$[i]) {
this.timerObserver$[i].unsubscribe();
}
}
}
ngOnDestroy() {
if (this.destroy$[this.selectedIndex] != undefined) {
this.destroy$[this.selectedIndex].next(true);
}
}
}