Men*_*imE 6 javascript typescript angular-material angular angular6
我最近开始修改一个基于 Angular 6 的项目,但遇到了一些问题。因此,我有(假设)4 个 Mat-Select 字段,分别用于语言、货币、国家和组织。
最初所有下拉菜单都有 10 个默认值,我通过调用 API 来获取。我的要求是,一旦用户滚动到选择下拉菜单时打开的 Mat-Options 框的末尾,就进行另一个 API 调用。
我已经提到了这个问题,它工作正常,但有一些问题,我注意到了。该答案涵盖了一个领域的解决方案。如果我们使用多个字段,我们是否必须重复代码?
这是HTML
<mat-select [disabled]="isDisabled" [(ngModel)]="model.currency" name="currency" (selectionChange)="OnChange('currency',$event.value)" #currency>
<mat-option [value]="getCurrency.currencyCode" *ngFor="let getCurrency of fetchCurrency |
filternew:searchCurrencyvaluedrop">{{ getCurrency.currencyDescription }}
</mat-option>
</mat-select>
<mat-select [disabled]="isDisabled" [(ngModel)]="model.language" name="language"
(selectionChange)="OnChange('language', $event.value)" #language>
<mat-option [value]="getLanguage.languageDescription" *ngFor="let getLanguage of fetchLanguage |
filternew:searchLanguagevaluedrop">{{ getLanguage.languageDescription }}</mat-option>
</mat-select>
Run Code Online (Sandbox Code Playgroud)
为简单起见,我只添加了两个字段。以下是 .ts 中的代码:
viewIndex = 0;
windowSize = 10;
private readonly PIXEL_TOLERANCE = 3.0;
ngAfterViewInit() {
this.selectElemCu.openedChange.subscribe((event) =>
this.registerPanelScrollEventCurrency(event)
);
this.selectElem.openedChange.subscribe((event) =>
this.registerPanelScrollEventLang(event)
);
}
//for language field
registerPanelScrollEventLang(e) {
if (e) {
const panel = this.selectElem.panel.nativeElement;
panel.addEventListener('scroll', event => this.loadNextOnScrollLang(event, this.selectElem.ngControl.name));
}
}
loadNextOnScrollLang(event, select_name) {
if (this.hasScrolledToBottomLang(event.target)) {
this.viewIndex += this.windowSize;
this.modifyPageDetails(select_name)
this.appService.getAllLanguages(this.standardPageSizeObj, resp => {
console.log('list of languages', resp)
this.fetchLanguage.push(...resp['data'])
}, (error) => {
});
}
}
private hasScrolledToBottomLang(target): boolean {
return Math.abs(target.scrollHeight - target.scrollTop - target.clientHeight) < this.PIXEL_TOLERANCE;
}
Run Code Online (Sandbox Code Playgroud)
货币下拉代码保持不变。所以,重复是我的第一个问题。第二个是在滚动时进行了两个 API 调用,而不是一个。我可以接受,但是因为有 6 个字段,所以重复太多了。
由于某些安全限制,我什至不能使用外部库。有没有更好的方法来实现这一点。如果需要更多说明,请告诉我。谢谢
我们可以创建一个指令来为我们处理这种滚动逻辑,并且可以防止代码重复。
这是一个演示:https://stackblitz.com/edit/angular-ivy-m2gees ?file=src/app/mat-select-bottom-scroll.directive.ts
这是一个简短的解释:
创建一个自定义指令并获取其中的引用MatSelect。
import {Directive,ElementRef,EventEmitter,Input,OnDestroy,Output} from '@angular/core';
import { MatSelect } from '@angular/material/select/';
import { fromEvent, Subject } from 'rxjs';
import { filter, switchMap, takeUntil, throttleTime } from 'rxjs/operators';
@Directive({
selector: '[appMatSelectScrollBottom]'
})
export class MatSelectScrollBottomDirective implements OnDestroy {
private readonly BOTTOM_SCROLL_OFFSET = 25;
@Output('appMatSelectScrollBottom') reachedBottom = new EventEmitter<void>();
onPanelScrollEvent = event => {};
unsubscribeAll = new Subject<boolean>();
constructor(private matSelect: MatSelect) {
this.matSelect.openedChange
.pipe(filter(isOpened => !!isOpened),
switchMap(isOpened =>fromEvent(this.matSelect.panel.nativeElement, 'scroll').pipe(throttleTime(50))), //controles the thrasold of scroll event
takeUntil(this.unsubscribeAll)
)
.subscribe((event: any) => {
console.log('scroll');
// console.log(event, event.target.scrollTop, event.target.scrollHeight);
if (
event.target.scrollTop >= (event.target.scrollHeight - event.target.offsetHeight - this.BOTTOM_SCROLL_OFFSET)) {
this.reachedBottom.emit();
}
});
}
ngOnDestroy(): void {
this.unsubscribeAll.next(true);
this.unsubscribeAll.complete();
}
}
Run Code Online (Sandbox Code Playgroud)
一旦滚动到达底部,该指令就会发出一个事件。
我们从该事件开始openedChange,然后将switchMap其编辑为选择面板的滚动事件。一旦新的打开事件触发,SwitchMap 将自动取消订阅旧的滚动事件。
在您的组件中使用此指令来侦听事件,如下所示。
<mat-form-field>
<mat-select placeholder="Choose a Doctor" (openedChange)="!$event && reset()"
(appMatSelectScrollBottom)="loadAllOnScroll()"><!-- liste to the event and call your load data function -->
<mat-option *ngFor="let dr of viewDoctors;let i = index">{{dr}}</mat-option>
</mat-select>
</mat-form-field>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
134 次 |
| 最近记录: |