问题原因分析。
- 初始化时,下来位置就通过目标元素(nz-select等)确定下来了。所以随内容元素的滚动不会在重新计算下拉框的位置。从而出现错位问题(感兴趣可以去看下nz-dropdown是怎么生成的)
解决方式
- 既然知道原因了,那就可以通过监听滚动,不断重新计算nz-dropdown的位置
- 以为nz-select的例子为例,代码如下
<button nz-button (click)="createModal()" [nzType]="'dashed'" [nzSize]="'small'">
<span>test select</span>
</button>
<template #detialModal>
<div>123456456</div>
</template>
<ng-template #detialModal>
<div #onModalContentScroll>
<nz-select [(ngModel)]="selectedValue" nzAllowClear nzPlaceHolder="Choose" nzShowSearch
class="width-100">
<nz-option-group nzLabel="Manager">
<nz-option nzValue="jack" nzLabel="Jack"></nz-option>
<nz-option nzValue="lucy" nzLabel="Lucy"></nz-option>
</nz-option-group>
<nz-option-group nzLabel="Engineer">
<nz-option nzValue="tom" nzLabel="Tom"></nz-option>
</nz-option-group>
</nz-select>
<div style="height: 800px;">撑大modal内容</div>
</div>
</ng-template>
import { Component, NgZone, TemplateRef, ViewChild, ViewChildren, QueryList } from '@angular/core';
import { NzModalRef, NzModalService } from 'ng-zorro-antd/modal';
import { NzSelectComponent } from 'ng-zorro-antd/select';
import { take } from 'rxjs';
@Component({
selector: 'app-dome',
templateUrl: './dome.component.html',
styleUrls: ['./dome.component.less']
})
export class DomeComponent {
@ViewChild('detialModal', { static: true }) detialModal!: TemplateRef<{}>;
@ViewChildren(NzSelectComponent) selectRefs!: QueryList<NzSelectComponent>;
selectedValue = 'lucy';
modalRef!: NzModalRef;
constructor(private modal: NzModalService, private ngZone: NgZone) { }
createModal() {
this.modalRef = this.modal.create({
nzTitle: 'Modal Title',
nzContent: this.detialModal,
nzClosable: false,
nzOnOk: () => new Promise(resolve => setTimeout(resolve, 1000))
});
this.modal.afterOpen.subscribe(() => {
this.ngZone.onStable
.asObservable()
.pipe(take(1))
.subscribe(() => {
const modalContentElement =
this.modal.containerInstance.modalElementRef.nativeElement
.parentElement;
if (modalContentElement) {
modalContentElement.addEventListener('scroll', scrollListener);
}
});
});
this.modal.afterClose.subscribe(() => {
const modalContentElement =
this.modal.containerInstance.modalElementRef.nativeElement
.parentElement;
if (modalContentElement) {
modalContentElement.removeEventListener('scroll', scrollListener);
}
});
}
}