Clarity Datagrid列输入过滤器在移动到分页网格中的下一页后,第一次按键时失去焦点



使用清晰的数据网格版本2.3看到一个问题,如果用户开始在datagrid列过滤器的输入字段中键入内容,那么一旦按下某个键,过滤器输入就会自动聚焦。

由于数据网格是分页和服务器驱动的,这导致API在在去抖动时间之后按下键。

输入字段外的自动焦点导致过滤器仅具有单个字符,并且由于脱骨仅为800,因此触发API。

已经查看了github的任何报告问题的清晰度,看起来不像其报告的问题或任何有类似问题的人。

预期的行为应该是输入焦点不应该发生,直到用户将光标移开或按下回车键,也就是说,反跳应该启动,之后应该调用api。

HTML:
<clr-datagrid
(clrDgRefresh)= refreshDataGrid($event)>
...
</clr-datagrid>
TS Component:
debouncer = new Subject<any>();
ngOnInit() {
this.debouncer.asObservable().pipe(
debounceTime(800)
).subscribe(state => {
// do something here.. like call an API to filter the grid.
})
}
refreshDataGrid(state) {
this.debouncer.next(state);
}

感谢您的帮助。

目前我正在破解我的组件,以确保在用户这样做之前,不会丢失对输入字段的关注。

refreshDataGrid(state) {
const isClrFilterInputField = document.querySelector('.datagrid-filter .clr-input');
if (isClrFilterInputField instanceof HTMLElement) {
isClrFilterInputField.focus();
}
this.debouncer.next(state);
}

这仍然不是一个干净的答案,但就我所搜索的而言,这似乎是数据网格本身的一个问题,直到我收到一个更干净的答案。

升级版本很可能已经修复了此问题。但要检查一下。

不幸的是,我认为我们设计的数据网格是为了在每个过滤器值更改时发出更改,并在消费者认为合适的情况下在应用程序端进行去抖动。

也就是说,完成你所描述的是可能的。我已经根据事件实现了一个快速而肮脏的保护,但可能还有更好的方法。我将在这里添加代码片段,并在末尾添加到工作堆栈litz的链接。

你在正确的轨道上与debobuncer。但我们不需要随着时间的推移而退缩,我们只需要对某些事件"退缩"。

如果我们用@HostListener来取消对过滤器输入的点击,而不是随着时间的推移而取消?(我将把它作为一个练习留给您为focusin事件实现HostListener,因为focusin bubble是up而blur不是(。要做到这一点,我们需要:

  1. 可以在筛选器输入上听到keydown.enter事件的主机侦听器
  2. 阻止请求的警卫
  3. 在用户输入文本时存储数据网格状态的属性

通常,代码需要:

  1. 在组件初始化时获取数据,但除非有指示,否则不会在初始化之后获取数据
  2. 跟踪从数据网格发出的状态事件
  3. 监听keydown.enter事件(以及任何其他事件,如过滤器输入focusout,因为它会冒泡,不像blur(
  4. 检查事件是否是在数据网格筛选器输入上生成的
  5. 解除警卫职务
  6. 提出请求
  7. 重新招募警卫

这里有一个粗略的尝试:

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);
}
}

这是一个工作堆栈litz:https://stackblitz.com/edit/so-60980488

相关内容

  • 没有找到相关文章

最新更新