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

循环渲染Kendo DropDownLists及数据过滤的问题排查

Kendo下拉框循环渲染问题解答

视图代码

@for (var i = 0; i < Model.ApprovingRoles.Count; i++)
{
    <div class="col-lg-6">
        @(Html.Kendo().DropDownListFor(m => m.ApprovingRoles[i])
              .Size(ComponentSize.Medium)
              .Rounded(Rounded.Medium)
              .FillMode(FillMode.Outline)
              .OptionLabel("Select " + Model.ApprovingRoles[i].Name)
              .HtmlAttributes(new { style = "width: 100%", required = "required", validationmessage = "Value required" })
              .DataTextField(nameof(SystemUserModel.EmployeeName))
              .DataValueField(nameof(SystemUserModel.Id))
              .Filter(FilterType.Contains)
              .DataSource(source =>
              {
                  source.Read(read =>
                  {
                    read.Action("GetUsersByRoleId", "Api").Data(Model.ApprovingRoles[i].Id.ToString());
                  }).ServerFiltering(true);
              })
              .Height(500)
            )
    </div>
}

疑问与当前现象

疑问

  1. 这种循环渲染下拉框的方式是否正确?
  2. 每个下拉框需通过GetUsersByRoleId API,以m.ApprovingRoles[i].Id作为过滤条件,是否配置正确?
  3. read.Action().Data()的设置是否正确?

当前现象

  • 正确显示4个下拉框
  • 选项标签正确
  • 下拉框无数据
  • GetUsersByRoleId接口接收的int类型参数roleId始终为0

问题解答

1. 循环渲染下拉框的方式是否正确?

循环渲染的逻辑本身没问题,但存在闭包陷阱风险——如果直接在循环中引用i,后续绑定的数据源或事件可能会引用循环结束后的i值。不过你当前下拉框数量显示正确,说明渲染阶段没有问题,数据源无数据的问题出在参数传递上。

2. API过滤条件配置是否正确?

逻辑方向是对的,但实现方式错误,导致接口接收的roleId始终为0。核心问题是Data()方法的使用方式不符合Kendo的要求:你直接传递了Model.ApprovingRoles[i].Id.ToString(),这会在视图渲染时把当前i对应的Id硬编码成字符串,但Kendo的Data()需要的是一个JavaScript函数,用来动态生成请求参数。

3. read.Action().Data()的设置是否正确?

完全错误。正确的用法是通过JavaScript函数动态传递参数,同时要避免闭包陷阱。


修复方案

方案一:局部变量捕获Id+匿名JS函数

在循环内创建局部变量捕获当前的roleId,避免闭包问题,同时传递返回参数的匿名JS函数:

@for (var i = 0; i < Model.ApprovingRoles.Count; i++)
{
    // 捕获当前循环的roleId,避免闭包陷阱
    var currentRoleId = Model.ApprovingRoles[i].Id;
    <div class="col-lg-6">
        @(Html.Kendo().DropDownListFor(m => m.ApprovingRoles[i])
              // 保留原有配置...
              .DataSource(source =>
              {
                  source.Read(read =>
                  {
                      read.Action("GetUsersByRoleId", "Api")
                          .Data($"function() {{ return {{ roleId: {currentRoleId} }}; }}");
                  }).ServerFiltering(true);
              })
              // 保留原有配置...
            )
    </div>
}

方案二:HTML Data属性+全局JS函数

把roleId存储到下拉框的HTML Data属性中,通过全局JS函数读取并传递:

@for (var i = 0; i < Model.ApprovingRoles.Count; i++)
{
    <div class="col-lg-6">
        @(Html.Kendo().DropDownListFor(m => m.ApprovingRoles[i])
              .HtmlAttributes(new { 
                  style = "width: 100%", 
                  required = "required", 
                  validationmessage = "Value required",
                  data_role_id = Model.ApprovingRoles[i].Id // 存储roleId到Data属性
              })
              // 保留原有配置...
              .DataSource(source =>
              {
                  source.Read(read =>
                  {
                      read.Action("GetUsersByRoleId", "Api")
                          .Data("getDropdownRoleId"); // 指定全局JS函数名
                  }).ServerFiltering(true);
              })
              // 保留原有配置...
            )
    </div>
}

// 在视图底部添加全局JS函数
<script>
function getDropdownRoleId() {
    // 获取当前触发请求的下拉框实例,读取Data属性
    var dropdownElement = $(this);
    return {
        roleId: dropdownElement.data("role-id")
    };
}
</script>

额外检查项

  1. 确认后端GetUsersByRoleId接口的参数名是roleId,大小写完全匹配;
  2. 直接通过浏览器地址栏测试接口:/Api/GetUsersByRoleId?roleId=xxx(替换xxx为有效角色Id),确认能返回正确的用户列表。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 03:45:32