Skip to content

Commit

Permalink
fix(module:spin): make delay behave more accurately (#5930)
Browse files Browse the repository at this point in the history
* docs: remove useless CSS

* fix(module:spin): use delay only to activate spinner

This also cleans up the rxjs in this component which would actually create
a memory leak over time if the delay input changes a lot (which is very
hypothetical).

fixes #5926

* fix(module:spin): respect delay on init

fixes #5928
  • Loading branch information
Airblader authored Oct 16, 2020
1 parent 7fbeaf7 commit 5c901a0
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 26 deletions.
14 changes: 1 addition & 13 deletions components/spin/demo/delay-and-debounce.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,4 @@ title:

## en-US

Specifies a delay for loading state. If `spinning` ends during delay, loading status won't appear.


````css
.example {
text-align: center;
background: rgba(0,0,0,0.05);
border-radius: 4px;
margin-bottom: 20px;
padding: 30px 50px;
margin: 20px 0;
}
````
Specifies a delay for loading state. If `spinning` ends during delay, loading status won't appear.
19 changes: 10 additions & 9 deletions components/spin/spin.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ import { NzConfigKey, NzConfigService, WithConfig } from 'ng-zorro-antd/core/con
import { BooleanInput, NumberInput, NzSafeAny, NzSizeLDSType } from 'ng-zorro-antd/core/types';
import { InputBoolean, InputNumber } from 'ng-zorro-antd/core/util';

import { BehaviorSubject, Subject } from 'rxjs';
import { debounceTime, mergeMap, takeUntil } from 'rxjs/operators';
import { BehaviorSubject, ReplaySubject, Subject, timer } from 'rxjs';
import { debounce, distinctUntilChanged, startWith, switchMap, takeUntil } from 'rxjs/operators';

const NZ_CONFIG_MODULE_NAME: NzConfigKey = 'spin';

Expand Down Expand Up @@ -72,20 +72,21 @@ export class NzSpinComponent implements OnChanges, OnDestroy, OnInit {
@Input() @InputBoolean() nzSpinning = true;
private destroy$ = new Subject<void>();
private spinning$ = new BehaviorSubject(this.nzSpinning);
private delay$ = new BehaviorSubject(this.nzDelay);
isLoading = true;
private delay$ = new ReplaySubject<number>(1);
isLoading = false;

constructor(public nzConfigService: NzConfigService, private cdr: ChangeDetectorRef) {}

ngOnInit(): void {
const loading$ = this.spinning$.pipe(
mergeMap(() => this.delay$),
mergeMap(delay => {
const loading$ = this.delay$.pipe(
startWith(this.nzDelay),
distinctUntilChanged(),
switchMap(delay => {
if (delay === 0) {
return this.spinning$;
} else {
return this.spinning$.pipe(debounceTime(delay));
}

return this.spinning$.pipe(debounce(spinning => timer(spinning ? delay : 0)));
}),
takeUntil(this.destroy$)
);
Expand Down
20 changes: 16 additions & 4 deletions components/spin/spin.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,19 +83,31 @@ describe('spin', () => {
});

it('should delay work', fakeAsync(() => {
testComponent.delay = 500;
fixture.detectChanges();
tick();
fixture.detectChanges();
testComponent.delay = 500;

// true -> false
// This should work immediately
testComponent.spinning = false;
fixture.detectChanges();
tick();
fixture.detectChanges();
expect(spin.nativeElement.querySelector('.ant-spin')).toBeDefined();
expect(spin.nativeElement.querySelector('.ant-spin')).toBeNull();

// false -> true
// This should be debounced
testComponent.spinning = true;
fixture.detectChanges();
tick(1000);
tick();
fixture.detectChanges();
expect(spin.nativeElement.querySelector('.ant-spin')).toBeNull();

fixture.detectChanges();
tick(1000);
fixture.detectChanges();
expect(spin.nativeElement.querySelector('.ant-spin')).toBeDefined();
}));

it('should wrapper work', fakeAsync(() => {
Expand Down Expand Up @@ -123,7 +135,7 @@ describe('spin', () => {

@Component({
template: `
<ng-template #indicatorTemplate><i nz-icon nzType="loading" style="font-size: 24px;"></i> </ng-template>
<ng-template #indicatorTemplate><i nz-icon nzType="loading" style="font-size: 24px;"></i></ng-template>
<nz-spin [nzTip]="tip" [nzSize]="size" [nzDelay]="delay" [nzSpinning]="spinning" [nzSimple]="simple" [nzIndicator]="indicator">
<div>test</div>
</nz-spin>
Expand Down

0 comments on commit 5c901a0

Please sign in to comment.