Фильтр ввода столбца Clarity Datagrid теряет фокус при первом нажатии клавиши после перехода на следующую страницу в разбитой на страницы сетке - PullRequest
1 голос
/ 02 апреля 2020

Использование версии 2.3 ясности сетки данных. Видит проблему, когда, если пользователь начинает вводить в поле ввода фильтра столбца сетки данных, вход фильтра автоматически фокусируется при нажатии клавиши.

Поскольку сетка данных разбит на страницы и управляется сервером, поэтому API запускается сразу после нажатия клавиши по истечении времени отката.

Автоматический c фокус вне поля ввода приводит к тому, что фильтр имеет только один персонаж и API срабатывают, так как дебоус только 800.

Посмотрел 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);
}

Любая помощь приветствуется.

Ответы [ 2 ]

0 голосов
/ 02 апреля 2020

К сожалению, я думаю, что мы разработали сетку данных для выдачи изменений при каждом изменении значения фильтра с устранением неполадок, предназначенных для выполнения на стороне приложения, как потребители считают нужным.

Тем не менее, можно достичь sh что вы описываете. Я реализовал быструю и грязную охрану, основанную на событиях, но могут быть и лучшие способы. Я добавлю здесь фрагменты кода и ссылку на рабочий стек в конце.

Вы находитесь на правильном пути с установщиком. Но нам не нужно отказываться от времени, нам нужно только «отказываться» от определенных событий.

Вместо того, чтобы отказываться от времени, что, если мы откажемся с @HostListener для кликов на входе фильтра? (Я оставлю это в качестве упражнения для вас, чтобы реализовать HostListener для события focusin, так как фокусировка пузыря вверх и размытия не происходит). Для этого нам нужно:

  1. Hostlistener, который может слышать событие keydown.enter на входе фильтра
  2. Защита для предотвращения запросов
  3. Свойство для хранения Состояние сетки данных при вводе пользователем текста

В общем случае код должен:

  1. Извлекать данные, когда компоненты компонента, но не после, если не указано
  2. Отслеживать события состояния, которые отправляются из сетки данных
  3. прослушивание событий keydown.enter (и любых других событий, таких как фокусировка входного сигнала фильтра - поскольку он пузырится, в отличие от размытия)
  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);
    }
  }

Вот рабочий стек стека: https://stackblitz.com/edit/so-60980488

0 голосов
/ 02 апреля 2020

В настоящее время я взламываю свой компонент, чтобы убедиться, что фокус не теряется на поле ввода, пока пользователь не сделает этого.

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

Это все еще не чистый ответ, но насколько как я искал, это похоже на проблему с самой сеткой ясности данных, пока я не получу ответ от кого-то с более ясным ответом.

Скорее всего, в обновленной версии это может быть исправлено. Еще бы проверить это.

...