ASP.NET MVC Kendo Grid setOptions如何处理列删除后的架构变更?
问题场景
我有一个ASP.NET MVC的Kendo Grid,支持保存列顺序和可见性(类似Telerik的状态持久化功能),网格配置已持久化到数据库。当在C#模型中移除某列后,网格加载时抛出以下错误:
ReferenceError: ColumnName is not defined
at eval (eval at compile (kendo.all.js:234:30), :3:3247)
at init._rowsHtml (kendo.all.js:70687:37)
at init._renderContent (kendo.all.js:71510:34)
错误中的ColumnName是已移除列在客户端模板中使用的属性,格式为#= ColumnName #。想知道是否能在调用setOptions时自动处理这类差异,比如移除当前模型不存在的列,或者忽略客户端模板的错误?目前只想到两个不太理想的方案:删除所有用户的持久化设置,或者编写迁移函数修改选项对象移除过时列。
解决方案
1. 在setOptions前过滤持久化列配置
从数据库加载持久化选项后,先和当前网格的列配置做对比,自动剔除不存在的列:
// 从后端获取的持久化配置 var persistedOptions = /* 数据库返回的JSON数据 */; // 获取当前网格的有效列字段集合 var currentColumnFields = $("#grid").data("kendoGrid").columns.map(col => col.field); // 过滤持久化列,仅保留当前存在的列 persistedOptions.columns = persistedOptions.columns.filter(col => { return currentColumnFields.includes(col.field); }); // 应用过滤后的配置 $("#grid").data("kendoGrid").setOptions(persistedOptions);
该方法能精准移除过时列,同时保留用户其他合法的持久化设置(如列顺序、可见性)。
2. 全局扩展setOptions方法
如果需要所有网格都自动处理这类兼容性问题,可以扩展Kendo Grid的原生方法:
(function ($) { var originalSetOptions = kendo.ui.Grid.fn.setOptions; kendo.ui.Grid.fn.setOptions = function(options) { if (options.columns && this.columns) { var currentFields = this.columns.map(col => col.field); // 自动过滤无效列 options.columns = options.columns.filter(col => currentFields.includes(col.field)); } // 调用原生方法完成配置设置 originalSetOptions.call(this, options); }; })(jQuery);
只需在全局脚本中引入这段代码,所有网格调用setOptions时都会自动处理过时列,无需逐个页面修改。
3. 客户端模板添加容错逻辑
如果无法修改持久化配置,可以临时给客户端模板添加空值判断,避免字段不存在报错:
// 原模板:#= ColumnName # // 修改为容错模板:#= typeof ColumnName !== 'undefined' ? ColumnName : '' #
此方法适合应急,但需要提前修改所有可能被移除列的模板,不如前两种方案彻底。
总结
优先推荐前两种方案,从根源上过滤无效列配置,既能解决报错问题,又能保留用户的个性化设置,比删除所有配置或手动迁移更友好。
内容的提问来源于stack exchange,提问作者Yehor Androsov

