You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vaadin Grid:如何控制过滤器输入触发dataProvider的时机?

解决Vaadin v24中Grid过滤器需点击按钮才触发DataProvider的问题

问题原因

Vaadin v24的vaadin-grid-filter组件新增了SlotController,会自动监听插槽内vaadin-text-field的value-changed事件,实时同步到过滤器的value属性,进而触发_filterChanged观察者,最终自动调用Grid的dataProvider回调。而v14版本无此自动同步逻辑,因此可以手动控制触发时机。

实现方案

以下提供三种可行方案,根据你的场景选择:

方案一:自定义GridFilter组件,手动控制过滤值同步

继承官方vaadin-grid-filter,重写控制器逻辑,移除自动同步,新增手动触发方法:

import { GridFilter } from '@vaadin/grid/src/vaadin-grid-filter.js';
import { SlotController } from '@vaadin/component-base/src/slot-controller.js';

class ManualGridFilter extends GridFilter {
  ready() {
    super.ready();
    // 替换原控制器,移除value-changed自动同步逻辑
    this._filterController = new SlotController(this, '', 'vaadin-text-field', {
      initializer: (field) => {
        this._textField = field; // 仅保存文本框引用,不绑定事件
      },
    });
    this.addController(this._filterController);
  }

  // 手动触发过滤的方法
  applyFilter() {
    if (this._textField) {
      this.value = this._textField.value; // 同步值,触发过滤
    }
  }
}

customElements.define('manual-grid-filter', ManualGridFilter);

使用方式:

<manual-grid-filter path="yourField">
  <vaadin-text-field placeholder="输入搜索内容"></vaadin-text-field>
</manual-grid-filter>
<button id="searchBtn">搜索</button>

<script>
document.getElementById('searchBtn').addEventListener('click', () => {
  document.querySelector('manual-grid-filter').applyFilter();
});
</script>

方案二:拦截文本框事件,阻止自动同步

无需自定义组件,直接在页面中拦截vaadin-text-field的value-changed事件,阻止GridFilter的自动同步,点击按钮时手动赋值:

<vaadin-grid-filter id="fieldFilter" path="yourField">
  <vaadin-text-field id="filterInput" placeholder="输入搜索内容"></vaadin-text-field>
</vaadin-grid-filter>
<button id="searchBtn">搜索</button>

<script>
const filter = document.getElementById('fieldFilter');
const input = document.getElementById('filterInput');

// 在捕获阶段阻止事件,避免GridFilter的监听触发
input.addEventListener('value-changed', (e) => {
  e.stopImmediatePropagation();
}, true);

// 点击按钮时手动同步过滤值
document.getElementById('searchBtn').addEventListener('click', () => {
  filter.value = input.value;
});
</script>

方案三:完全手动控制DataProvider触发

绕过GridFilter的自动逻辑,自己维护过滤条件,点击按钮时手动触发DataProvider:

<vaadin-text-field id="filterInput" placeholder="输入搜索内容"></vaadin-text-field>
<button id="searchBtn">搜索</button>
<vaadin-grid id="dataGrid"></vaadin-grid>

<script>
const grid = document.getElementById('dataGrid');
const input = document.getElementById('filterInput');
let currentFilter = '';

// 自定义DataProvider,使用手动维护的过滤条件
grid.dataProvider = async (params, callback) => {
  // 这里替换为你的数据源请求逻辑,传入currentFilter
  const response = await fetch(`/your-api-endpoint?filter=${encodeURIComponent(currentFilter)}`);
  const data = await response.json();
  callback(data.items, data.totalCount);
};

// 点击按钮时更新过滤条件并刷新Grid
document.getElementById('searchBtn').addEventListener('click', () => {
  currentFilter = input.value;
  grid.refreshItems(); // 触发DataProvider调用
});
</script>

内容的提问来源于stack exchange,提问作者robg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 11:45:37