设置Filter属性后Kendo DropDownList组件出现异常
I’ve run into this exact frustrating issue before—when combining virtualization and filtering on a Kendo DropDownList, that "Add of undefined" error pops up when losing focus or selecting items, and only the close arrow works. Let’s break down why this happens and how to fix it:
Core Cause
The error typically stems from a mismatch between the component’s internal state (like tracked selected items or virtual scroll cache) and the filtered remote data. When filtering triggers a data reload, the DropDownList tries to update its selected items collection but can’t find the expected internal reference, leading to the undefined error.
Step-by-Step Solutions
1. Validate Data Source Configuration
First, make sure your remote data source is set up to properly support both virtualization and server-side filtering:
- Ensure your
schemaexplicitly defines thetotalfield (critical for virtualization to calculate scroll bounds, especially after filtering). - Confirm your API returns filtered data in the structure Kendo expects—usually an object with a
dataarray (the filtered results) and atotalcount (the total number of matching items). - Double-check that
serverFilteringandserverPagingare set totrue(since virtualization relies on server-side pagination, and filtering needs to be handled remotely too).
2. Fix Value Binding Configuration
If you’re binding to primitive values (like IDs instead of full objects), always set valuePrimitive: true. This is a common oversight that breaks virtualized/filtered DropDownLists—without it, the component tries to track full item objects that may no longer exist after filtering, leading to state conflicts.
3. Implement a Proper Value Mapper
Virtualized DropDownLists require a valueMapper function to map selected values to their positions in the full dataset. When filtering is enabled, this function needs to account for the filtered state to avoid mismatches:
virtual: { itemHeight: 26, valueMapper: function(options) { $.ajax({ url: "/api/your-value-mapper-endpoint", data: { values: options.value, filter: $("#dropdownlist").data("kendoDropDownList").filter() // Pass current filter to the API }, success: function(data) { options.success(data); } }); } }
Your backend should return the correct indices of the selected values within the filtered dataset.
4. Sync Selected State on Data Bound
Add a dataBound event handler to ensure the selected value still exists in the filtered dataset. If it doesn’t, clear the selection to prevent the component from trying to reference an item that’s no longer present:
dataBound: function(e) { var dropdown = this; var selectedValue = dropdown.value(); if (selectedValue) { // Check if the selected item exists in the current filtered view var itemExists = dropdown.dataSource.view().some(item => item.Value === selectedValue); if (!itemExists) { dropdown.value(null); } } }
5. Update Kendo UI Version
If you’re using an older version of Kendo UI, this might be a known bug that’s been fixed in newer releases. Check the Kendo release notes for fixes related to virtualization and filtering, then upgrade to the latest stable version.
Full Working Example
Here’s a consolidated configuration that incorporates all these fixes:
$("#virtual-dropdown").kendoDropDownList({ dataSource: { type: "json", transport: { read: { url: "/api/your-data-endpoint", dataType: "json" } }, schema: { data: "results", total: "totalCount" }, serverFiltering: true, serverPaging: true, pageSize: 20 }, virtual: { itemHeight: 26, valueMapper: function(options) { $.ajax({ url: "/api/your-value-mapper", data: { values: options.value, filter: $("#virtual-dropdown").data("kendoDropDownList").filter() }, success: function(data) { options.success(data); } }); } }, filter: "contains", valuePrimitive: true, dataTextField: "DisplayName", dataValueField: "Id", dataBound: function(e) { var dropdown = this; var selectedValue = dropdown.value(); if (selectedValue) { var itemExists = dropdown.dataSource.view().some(item => item.Id === selectedValue); if (!itemExists) { dropdown.value(null); } } } });
内容的提问来源于stack exchange,提问作者Francisco Garcia

