添加了 debounceTime(0),因为没有它,我的更改无法正确反映到用户界面,另外的好处是组合最新优化,但它破坏了我的单元测试。
get nativeWindow(): Window {
return window;
}
private resize$ = fromEvent(this.nativeWindow, 'resize').pipe(
debounceTime(50),
map(event => event.target as Window),
startWith(this.nativeWindow),
untilDestroyed(this)
);
protected dimensions$: Observable<{ width: number; height: number }> = combineLatest([this.resize$]).pipe(
withLatestFrom(this.elementRef$),
debounceTime(0),
map(([, ref]) => ({ width: ref.nativeElement.offsetWidth, height: ref.nativeElement.offsetHeight })),
filter(dim => dim.width > 0)
);
之前有效的示例单元测试。我正在使用@ngneat/spectator
it('should display cropped image', () => {
host.setHostInput({
assetCrop: {
type: 'CROP',
x: 100,
y: 100,
width: 200,
height: 200
}
});
expect(crop?.backgroundPosition).toBe('-100px -100px');
expect(crop?.backgroundSize).toBe('1000px 1000px');
});
我尝试使用fakeAsync和tick以及whenStable但没有成功
因此,在调查问题之后,问题似乎没有
debounceTime(0)
流尝试在调整大小过程完成之前获取尺寸。添加 setTimeout 使其工作,但我对解决方案不满意。
ngAfterViewInit(): void {
setTimeout(() => {
this.#imageWrapperDimensions$.next({
width: this.elementRef.nativeElement.offsetWidth,
height: this.elementRef.nativeElement.offsetHeight
});
});
}
private resize$: Observable<{ width: number; height: number }> = this.ngZone.runOutsideAngular(() =>
fromEvent(this.window, 'resize').pipe(
debounceTime(50),
map(event => event.target as Window),
startWith(this.window),
map(() => ({ width: this.elementRef.nativeElement.offsetWidth, height: this.elementRef.nativeElement.offsetHeight })),
untilDestroyed(this)
)
);
#imageWrapperDimensions$ = new Subject<{ width: number; height: number }>();
protected imageWrapperDimensions$: Observable<{ width: number; height: number }> = merge(
this.resize$,
this.#imageWrapperDimensions$
).pipe(filter(dim => dim.width > 0));