DevExtreme dxGrid 查找列形式显示 id 而不是 DisplayExpr

DevExtreme dxGrid lookup column form display id instead of DisplayExpr

我正在使用 DevExtreme dxGrid 来显示和编辑用户数据,并且我有一个查找列来选择用户部门。 数据在网格中正确显示,但在我按下编辑按钮后弹出表单显示查找字段显示部门的 id 值,而不是 DisplayExpr 中指定的值,但是当我单击下拉列表时显示的值正确。

我在 DevExpress 网站上搜索了很多,并尝试了他们所说的关于数据源和 JS 之间类型不匹配的所有内容,但没有任何效果。

cshtml代码:

 @(Html.DevExtreme().DataGrid().ID("gridContainer")
            .DataSource(d => d.WebApi().Controller("UsersApi").Key("Id").LoadAction("GetUsers").UpdateAction("Put"))
            .AllowColumnReordering(true)
            .AllowColumnResizing(true)
            .ColumnAutoWidth(true)
            .ColumnChooser(c => c.Enabled(true))
            .GroupPanel(groupPanel => groupPanel.Visible(true))
            .OnToolbarPreparing("OnToolbarPreparing")
            .OnEditorPreparing("OnEditorPreparing")
            .Editing(e =>
            {
                e.AllowUpdating(true);
                e.Mode(GridEditMode.Popup);
            })
            .Columns(c =>
            {
                c.Add().DataField("IsActive").Caption("Active").Width("100");
                c.Add().DataField("UserName").Caption("Username").Width("120").AllowEditing(false);
                c.Add().DataField("FullName").Caption("Full Name").Width("200");
                c.Add().DataField("Email").Width("250");
                c.Add().DataField("CreatedUtc")
                    .Caption("Created")
                    .DataType(GridColumnDataType.Date)
                    .CellTemplate(new JS("created_CellTemplate"))
                    .Visible(false)
                    .ShowInColumnChooser(true)
                    .AllowEditing(false)
                    .Width("80");
                c.Add().DataField("CreatedBy").Caption("Created By").Visible(false).ShowInColumnChooser(true).AllowEditing(false).Width("120");

                c.Add().DataField("LastAccessStr")
                    .Caption("Latest Access")
                    .CellTemplate(new JS("latestAccess_CellTemplate"))
                    .CalculateSortValue("LastAccessUtc")
                    .SortOrder(SortOrder.Desc)
                    .AllowEditing(false)
                    .Width("120");

                c.Add().DataField("LastLoginStr")
                    .Caption("Latest Login")
                    .CellTemplate(new JS("latestLogin_CellTemplate"))
                    .CalculateSortValue("LastLoginUtc")
                    .AllowEditing(false).Visible(false).ShowInColumnChooser(true)
                    .Width("120");
                c.Add().DataField("LastLoginIP").Caption("Latest Login IP").AllowEditing(false).Width("150");
                c.Add().DataField("PhoneNumber").Caption("Phone").Width("150").Visible(false).ShowInColumnChooser(true);
                c.Add().DataField("Role").Width("200");
                c.Add().DataField("DepartmentId").Caption("Department").Width(200).Lookup(
                    lookup => lookup
                    .DataSource(d => d.WebApi()
                    .Controller("DepartmentsApi")
                    .LoadAction("GetDepartment")
                    .Key("Id"))
                    .DisplayExpr("Name")
                    .ValueExpr("Id")

               );
            })
            .Summary(c =>
            {
                c.TotalItems(cc => cc.Add().Column("UserName").SummaryType(SummaryType.Count));
            })
            .Paging(paging => paging.PageSize(25))
            .Pager(pager =>
            {
                pager.ShowPageSizeSelector(true);
                pager.AllowedPageSizes(new List<int> { 10, 25, 50 });
                pager.ShowInfo(true);
            })
            .FilterRow(filterRow => filterRow
                .Visible(false)
                .ApplyFilter(GridApplyFilterMode.Auto)
            )
            .SearchPanel(searchPanel => searchPanel
            .Visible(true)
            .Width(240)
            .Placeholder("Search...")
        )

        .RowAlternationEnabled(true)
        .OnCellPrepared("cell_prepared")
)


<script>
    function created_CellTemplate(cellElement, cellInfo) {

        var tipid = cellInfo.data.Id;
        var sitetextid = cellInfo.data.Id + "s";

        $("<div id=" + tipid + "></div><div id=" + sitetextid + "><div>").text(cellInfo.data.ElapsedTime).appendTo(cellElement);

        $("#" + tipid).dxTooltip({
            target: "#" + sitetextid,
            showEvent: "dxhoverstart",
            hideEvent: "dxhoverend",
            position: "top",
            contentTemplate: function (contentElement) {

                var utcDate = new Date(cellInfo.data.CreatedUtc);
                contentElement.html("<b>" + convertUtcToLocal(utcDate) + "</b>");
            }
        });
    }

    function last_CellTemplate(cellElement, cellValue, cellDisplayValue, tipId, cellTextId) {
        if (cellDisplayValue === 'N/A') {
            $("<div id=" + tipId + "></div>").text(cellDisplayValue).appendTo(cellElement);
        } else {
            $("<div id=" + tipId + "></div><div id=" + cellTextId + "><div>").text(cellDisplayValue).appendTo(cellElement);
            $("#" + tipId).dxTooltip({
                target: "#" + cellTextId,
                showEvent: "dxhoverstart",
                hideEvent: "dxhoverend",
                position: "top",
                contentTemplate: function (contentElement) {
                    var utcDate = new Date(cellValue);
                    contentElement.html("<b>" + convertUtcToLocal(utcDate) + "</b>");
                }
            });
        }

    }

    function latestAccess_CellTemplate(cellElement, cellInfo) {
        var tipid = 'la_' + cellInfo.data.Id;
        var sitetextid = 'la_' + cellInfo.data.Id + "s";

        last_CellTemplate(cellElement, cellInfo.data.LastAccessUtc, cellInfo.data.LastAccessStr, tipid, sitetextid);
    }
    function latestLogin_CellTemplate(cellElement, cellInfo) {
        var tipid = 'll_' + cellInfo.data.Id;
        var sitetextid = 'll_' + cellInfo.data.Id + "s";

        last_CellTemplate(cellElement, cellInfo.data.LastLoginUtc, cellInfo.data.LastLoginStr, tipid, sitetextid);
    }

    function OnToolbarPreparing(e) {
        var dataGrid = e.component;
        var toolbarItems = e.toolbarOptions.items;

        toolbarItems.push({
            widget: 'dxButton',
            options: { icon: 'refresh', onClick: function () { dataGrid.refresh(); } },
            location: 'after'
        });

        toolbarItems.push({
            widget: 'dxButton',
            options: {
                icon: 'filter',
                hint: 'Show Filters',
                onClick: function (data) {
                    dataGrid.option('filterRow.visible', !dataGrid.option('filterRow.visible'));
                }
            },
            location: 'after'
        });

        toolbarItems.push({
            widget: 'dxButton',
            options: {
                icon: 'add',
                hint: 'New User',
                onClick: function (data) {
                    window.location.href = '/Admin/AddUser';
                }
            },
            location: 'after'
        });
    }

    function OnEditorPreparing(e) {
        if (e.dataField === 'Role') {
            e.cancel = true;
            var selectBox = $('<div id="role-editor"></div>').dxSelectBox({
                dataSource: "/Admin/GetAllRoles",
                value: e.value,
                onValueChanged: function (ev) {
                    e.setValue(ev.value);
                }
            });
            e.editorElement.html(selectBox);
        }
    }

    function cell_prepared(e) {
        if (e.rowType === "data" && e.column.command === "edit") {
            var isEditing = e.row.isEditing,
                $links = e.cellElement.find(".dx-link");

            $links.text("");

            if (isEditing) {
                $links.filter(".dx-link-save").addClass("dx-icon-save");
                $links.filter(".dx-link-cancel").addClass("dx-icon-revert");
            } else {
                $links.filter(".dx-link-edit").addClass("dx-icon-edit");
                $links.filter(".dx-link-delete").addClass("dx-icon-trash");
            }
        }
    }

</script>

问题在departmentId列。

UsersApiController.cs代码:

 public class UsersApiController : Controller
{
    private readonly UserManager<ApplicationUser> _userManager;
    private readonly IUnitOfWork _unitOfWork;

    public UsersApiController(UserManager<ApplicationUser> userManager, IUnitOfWork unitOfWork)
    {
        _userManager = userManager;
        _unitOfWork = unitOfWork;
    }

    [HttpGet]
    public async Task<IActionResult> GetUsers()
    {
        var users = new List<UserViewModel>();

        foreach (var user in _unitOfWork.ApplicationUsers.GetAll())
        {
            if (user.UserName.ToLower() == "admin")
                continue;
            var userRoles = await _userManager.GetRolesAsync(user);
            var userToAdd = new UserViewModel
            {
                Id = user.Id,
                UserName = user.UserName,
                FullName = user.FullName,
                Email = user.Email,
                IsActive = user.IsActive,
                PhoneNumber = user.PhoneNumber,
                CreatedUtc = user.CreatedUtc,
                ElapsedTime = DateHelper.GetElapsedTime(user.CreatedUtc),
                Role = user.Role,
                LastAccessUtc = user.LastAccess,
                LastAccessStr = DateHelper.GetElapsedTime(user.LastAccess),
                LastLoginIP = user.LastLoginIP,
                LastLoginUtc = user.LastLogin,
                LastLoginStr = DateHelper.GetElapsedTime(user.LastLogin),
                CreatedBy = user.CreatedByUsername,
                DepartmentId=user.DepartmentId
            };
            users.Add(userToAdd);
        }

        return Ok(users);
    }

DepartmentsApiController.cs代码:

 public class DepartmentsApiController : Controller
{
    private readonly UserManager<ApplicationUser> _userManager;
    private readonly IUnitOfWork _unitOfWork;

    public DepartmentsApiController(UserManager<ApplicationUser> userManager, IUnitOfWork unitOfWork)
    {
        _userManager = userManager;
        _unitOfWork = unitOfWork;
    }

    [HttpGet]
    public IActionResult GetDepartment()
    {
        var dep = _unitOfWork.DepartmentsRep.GetAll();

        return Ok(dep);
    }

请注意 departmentId 的类型是 Guid。 我也尝试用 string 类型替换 Guid 类型,但问题仍然存在。我还尝试在 UsersApiDepatementsApi 中使用 int 而不是 Guid,问题仍然存在。我正在尝试这样做,因为在 DevExpress 网站上,他们说这个问题是因为类型不匹配。 我附上了一张显示问题的图片。

首先你的示例代码有一些问题,你的 DepartmentsApiController 继承自 Controller 但 returns Ok(),它应该继承自 ApiController,其次,您的 GetDepartment 操作 returns a IActionResult,应该return一个IHttpActionResult


经过这些考虑,这里是您问题的答案,问题出在您的 GetDepartment 操作上,它看起来像这样

[HttpGet]
public IActionResult GetDepartment()
{
    var dep = _unitOfWork.DepartmentsRep.GetAll();

    return Ok(dep);
}

但应该是这样的

[HttpGet]
 public HttpResponseMessage GetDepartment(DataSourceLoadOptions oadOptions)
{
            var dep = _unitOfWork.DepartmentsRep.GetAll();

            return Request.CreateResponse(DataSourceLoader.Load(dep, loadOptions));
}

这里可以看到DevExpress官方的示例代码

剃刀

columns.Add()
            .DataField("ShipVia")
            .Caption("Shipping Company")
            .Lookup(lookup => lookup
                .DataSource(d => d.WebApi().Controller("GridData").LoadAction("ShippersLookup").Key("Value"))
                .ValueExpr("Value")
                .DisplayExpr("Text")
            );

API

[HttpGet]
public HttpResponseMessage ShippersLookup(DataSourceLoadOptions loadOptions)
{
            var lookup = from i in _nwind.Shippers
                         orderby i.CompanyName
                         select new
                         {
                             Value = i.ShipperID,
                             Text = i.CompanyName
                         };

            return Request.CreateResponse(DataSourceLoader.Load(lookup, loadOptions));
  }