不幸的是,我认为我们设计了数据网格以在每个过滤器值更改时发出更改,并在消费者认为合适的情况下在应用程序端进行去抖动。
也就是说,有可能完成你所描述的。我已经根据事件实施了一个快速而肮脏的守卫,但可能有更好的方法。我将在此处添加代码片段,并在最后添加指向正在运行的 stackblitz 的链接。
使用去抖动器,您走在正确的轨道上。但是我们不需要随着时间去抖动,我们只需要在某些事件上“去抖动”。
如果我们使用@HostListener 对过滤器输入的点击进行去抖动,而不是随着时间去抖动呢?(我将把它作为练习留给您为 focusin 事件实现一个 HostListener,因为 focusin 气泡上升而 blur 没有)。为此,我们需要:
- 可以在过滤器输入上听到 keydown.enter 事件的 Hostlistener
- 防止请求的守卫
- 在用户输入文本时存储数据网格状态的属性
一般来说,代码需要:
- 除非有指示,否则在组件启动时获取数据,而不是之后
- 跟踪从数据网格发出的状态事件
- 听 keydown.enter 事件(以及任何其他事件,如过滤器输入焦点输出 - 因为它会冒泡,不像模糊)
- 检查事件是否在数据网格过滤器输入上生成
- 解雇警卫
- 提出请求
- 重新招募守卫
这是一个粗略的尝试:
export class DatagridFullDemo {
refreshGuard = true; // init to true to get first run data
debouncer = new Subject<any>(); // this is now an enter key debouncer
datagridState: ClrDatagridStateInterface; // a place to store datagrid state as it is emitted
ngOnInit() {
// subscribe to the debouncer and pass the state to the doRefresh function
this.debouncer.asObservable().subscribe(state => {
this.doRefresh(state);
});
}
// a private function that takes a datagrid state
private doRefresh(state: ClrDatagridStateInterface) {
// Guard against refreshes ad only run them when true
if (this.refreshGuard) {
this.loading = true;
const filters: { [prop: string]: any[] } = {};
console.log("refresh called");
if (state.filters) {
for (const filter of state.filters) {
const { property, value } = <{ property: string; value: string }>(
filter
);
filters[property] = [value];
}
}
this.inventory
.filter(filters)
.sort(<{ by: string; reverse: boolean }>state.sort)
.fetch(state.page.from, state.page.size)
.then((result: FetchResult) => {
this.users = result.users;
this.total = result.length;
this.loading = false;
this.selectedUser = this.users[1];
// Set the guard back to false to prevent requests
this.refreshGuard = false;
});
}
}
// Listen to keydown.enter events
@HostListener("document:keydown.enter", ["$event"]) enterKeydownHandler(
event: KeyboardEvent
) {
// Use a host listener that checks the event element parent to make sure its a datagrid filter
const eventSource: HTMLElement = event.srcElement as HTMLElement;
const parentElement = eventSource.parentElement as HTMLElement;
if (parentElement.classList.contains("datagrid-filter")) {
// tell our guard its ok to refresh
this.refreshGuard = true;
// pass the latest state to the debouncer to make the request
this.debouncer.next(this.datagridState);
}
}
refresh(state: ClrDatagridStateInterface) {
this.datagridState = state;
this.debouncer.next(state);
}
}
这是一个有效的堆栈闪电战: https ://stackblitz.com/edit/so-60980488