MVC中Kendo UI Grid用ClientTemplate与EditorTemplateName新建行报错解决
问题描述
我正在用Kendo UI Grid制作联系人列表,需求如下:
- 工具栏需包含新建联系人按钮
- 带有编辑、删除按钮的操作列
- 联系人组列:视图模型为字符串列表,显示模式下以逗号分隔展示,编辑模式下使用Kendo MultiSelect组件
目前页面渲染、删除、编辑功能均正常,但点击新建联系人按钮时,控制台抛出错误:Uncaught ReferenceError: ContactGroups is not defined。推测是新建行时,ClientTemplate中的JavaScript语句因ContactGroups未赋值导致的,求解决办法。
现有代码
主视图代码
@using MyProject.Contacts.Models; @using Kendo.Mvc.UI; @{ ViewBag.Title = "Contacts"; } <div id="contactsContainer" class=""> @(Html.Kendo().Grid<ContactsViewModel>() .Name("ContactsGrid") .Columns(columns => { columns.Bound(p => p.ContactName).Title("Contact Name").Width(200); columns.Bound(p => p.ContactGroups).ClientTemplate("#= displayContactGroups(ContactGroups)#").EditorTemplateName("ContactGroupsEditor").Title("ContactGroups").Width(200); columns.Command(command => { command.Edit().IconClass("k-icon k-i-edit"); command.Destroy().IconClass("k-icon k-i-delete"); } ).Title("Actions").Width(200); }) .NoRecords(n => n.Template("No Contacts to display")) .ToolBar(tools => { tools.Create().Text("Create New Contact"); }) .DataSource(dataSource => dataSource .Ajax() .PageSize(10) .Model(model => { model.Id(m => m.kendoId); } ) .Create(create => create.Action("CreateContact", "Contacts")) .Read(read => read.Action("GetContacts", "Contacts")) .Update(update => update.Action("UpdateContact", "Contacts")) .Destroy(destroy => destroy.Action("DeleteContact", "Contacts")) ) ) </div> <script> function displayContactGroups(contactGroups) { if (contactGroups == null) { return ""; } return contactGroups.join(", "); } </script>
ContactGroupsEditor部分视图代码
@model List<string> @(Html.Kendo().MultiSelect() .Name("ContactGroups") .DataValueField("Text") .DataTextField("Text") .BindTo(new List<SelectListItem> { new SelectListItem { Text = "GalacticEmpire"}, new SelectListItem { Text = "RebelAlliance"} }) .Value(Model) )
解决方法
方案1:修改ClientTemplate,提前判断变量是否存在
直接在ClientTemplate中增加对ContactGroups是否定义的判断,避免未定义变量传入函数:
columns.Bound(p => p.ContactGroups) .ClientTemplate("#= typeof ContactGroups !== 'undefined' ? displayContactGroups(ContactGroups) : '' #") .EditorTemplateName("ContactGroupsEditor") .Title("ContactGroups") .Width(200);
新建行时,ContactGroups未定义的情况下会直接返回空字符串,不会触发ReferenceError。
方案2:在DataSource模型中初始化默认值
在Grid的DataSource配置里,给ContactGroups字段设置默认的空列表,确保新建行时该字段有初始值:
.DataSource(dataSource => dataSource .Ajax() .PageSize(10) .Model(model => { model.Id(m => m.kendoId); // 初始化ContactGroups为空列表 model.Field(m => m.ContactGroups).DefaultValue(new List<string>()); }) .Create(create => create.Action("CreateContact", "Contacts")) .Read(read => read.Action("GetContacts", "Contacts")) .Update(update => update.Action("UpdateContact", "Contacts")) .Destroy(destroy => destroy.Action("DeleteContact", "Contacts")) )
这样新建行时ContactGroups会是一个空列表,displayContactGroups函数能正常处理,不会出现未定义的情况。
方案3:优化前端函数+模板兼容
如果不想修改后端配置,可以同时优化前端函数和模板:
- 升级
displayContactGroups函数,增加对未定义参数的处理:
function displayContactGroups(contactGroups) { if (contactGroups == null || typeof contactGroups === 'undefined') { return ""; } return contactGroups.join(", "); }
- 同时保留方案1的ClientTemplate判断,确保模板解析时不会直接报错。
内容的提问来源于stack exchange,提问作者Belgabad
相关产品推荐
相关产品推荐

