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

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:优化前端函数+模板兼容

如果不想修改后端配置,可以同时优化前端函数和模板:

  1. 升级displayContactGroups函数,增加对未定义参数的处理:
function displayContactGroups(contactGroups) {
    if (contactGroups == null || typeof contactGroups === 'undefined') {
        return "";
    }
    return contactGroups.join(", ");
}
  1. 同时保留方案1的ClientTemplate判断,确保模板解析时不会直接报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 07:54:58