首页 > 解决方案 > 我应该使用异步方法来选择我的 KendoUI 网格中的行吗?

问题描述

我在 KendoUI 网格上选择行时遇到问题。我有两个网格需要根据控制器返回的数据预先选择行。问题是选择过程无法始终如一地工作,因为似乎是数据访问时间,即控制器返回通过 ajax 函数客户端请求的数据所需的时间。

为了测试这个理论,我在控制器中放置了一个间隔来错开返回的数据,它起作用了,但同样,它并不一致。这是两个网格的代码:

容器网格

@(Html.Kendo().Grid<Vessel>()
    .Name("VesselGrid")
    .Columns(columns => {
        columns.Select().Width(50);
        columns.Bound(p => p.Id);
        columns.Bound(p => p.Name);
    })
    .Pageable()
    .Selectable(selectable => selectable.Mode(GridSelectionMode.Multiple))
    .Scrollable()
    .Filterable(ftb => ftb.Mode(GridFilterMode.Row))
    .PersistSelection()
    .HtmlAttributes(new { style = "height:550px;" })
    .DataSource(dataSource => dataSource
        .Ajax()
        .ServerOperation(true)
        .PageSize(20)
        .Model(m => m.Id(x => x.Id))
        .Read(read => read.Action("ReadVessels", "Core"))))

列网格

 @(Html.Kendo().Grid<VesselColumn>()
     .Name("columnGrid")
     .Columns(columns => {
         columns.Bound(p => p.Id);
         columns.Bound(p => p.ColumnName);
     })
     .Pageable()
     .Sortable(Sortable => Sortable.AllowUnsort(true))
     .Selectable(selectable => selectable.Mode(GridSelectionMode.Multiple))
     .Scrollable()
     .Filterable(ftb => ftb.Mode(GridFilterMode.Row))
     .PersistSelection()
     .HtmlAttributes(new { style = "height:550px;" })
     .DataSource(dataSource => dataSource
         .Ajax()
         .ServerOperation(true)
         .PageSize(20)
         .Model(m => m.Id(x => x.Id))
         .Read(read => read.Action("ReadVesselColumns", "Core"))))

这是在文档就绪时调用的 ajax 函数,它应该预先选择每个网格上的行。

$(function () {     
    $.ajax({
        type: 'POST',
        url: '/Test/ReadUserVessels',
        data: { Id: 230 },
        success: function (data) {
            setVessels(data);
        },
        error: function () {
            alert('error');
        }
    });

   
    $.ajax({
        type: 'POST',
        url: '/Test/ReadUserColumns',
        data: { Id: 230 },
        success: function (data) {
            setColumns(data);
        },
        error: function () {
            alert('error');
        }
    });

    function setVessels(data) {
        $(data.vessels).each(function (vIndex, vValue) {
            $("#vesselGrid").getKendoGrid()._selectedIds[vValue.VesselId] = true;
        });            
    }
    function setColumns(data) {
        $(data.columns).each(function (cIndex, cValue) {
            $("#columnGrid").getKendoGrid()._selectedIds[cValue.ColumnId] = true;
        });
    }
})

以下是向这些函数返回数据以突出显示行的控制器操作。

public async Task<JsonResult> ReadUserVessels(int? id) {
    IEnumerable<UserVessels> vessels = _userVesselService.GetUserVessels().Where(x => x.ViewId == id).ToList();
    return Json(new { success = true, vessels });
}
        
public async Task<JsonResult> ReadUserColumns(int? id) {
    IEnumerable<UserColumn> columns = _userColumnService.GetUserColumns().Where(x => x.ViewId == id).ToList();            
    return Json(new { success = true, columns});
}

如您所见,页面已加载,当文档准备好时,同时对两个控制器操作进行了两个 ajax 调用。从那里应该选择网格上的行并以蓝色突出显示。只有船舶网格会这样做。

我的猜测是,由于请求发出,无论处理网格上的行选择的过程,当列网格要求做同样的事情时仍在使用中。这是我通过为列网格的控制器操作设置 2 秒的间隔来测试的理论。它有效,但不一致。

所以,我的问题是,我应该使用异步控制器操作来访问数据吗?如果是这样,有人可以帮助我如何实现这一目标,还是我的方法不正确?

标签: c#entity-frameworkasp.net-corekendo-ui

解决方案


正在发生的事情是您的网格数据并不总是在文档准备就绪时填充,这就是您看到不一致行为的原因。

要解决此问题,请连接网格的数据绑定事件。检索到所有数据后,将触发数据绑定事件。然后,将您的 ajax 调用(ReadUserVessels 和 ReadUserColumns)从准备好的文档移动到各自网格的数据绑定事件处理程序。

代码示例:

Vessel Grid和js函数

@(Html.Kendo().Grid<Vessel>()
    .Name("VesselGrid")
    .Columns(columns => {
        columns.Select().Width(50);
        columns.Bound(p => p.Id);
        columns.Bound(p => p.Name);
    })
    .Pageable()
    .Selectable(selectable => selectable.Mode(GridSelectionMode.Multiple))
    .Scrollable()
    .Filterable(ftb => ftb.Mode(GridFilterMode.Row))
    .PersistSelection()
    .HtmlAttributes(new { style = "height:550px;" })
    .Events(events => events.DataBound("vesselGridDataBound"))
    .DataSource(dataSource => dataSource
        .Ajax()
        .ServerOperation(true)
        .PageSize(20)
        .Model(m => m.Id(x => x.Id))
        .Read(read => read.Action("ReadVessels", "Core"))))


<script>
  function vesselGridDataBound(e) {
    $.ajax({
        type: 'POST',
        url: '/Test/ReadUserVessels',
        data: { Id: 230 },
        success: function (data) {
            setVessels(data);
        },
        error: function () {
            alert('error');
        }
    });
  }
</script>


推荐阅读