DevExtreme dxGrid 查找列表单显示 id 而不是 DisplayExpr

Posted

技术标签:

【中文标题】DevExtreme dxGrid 查找列表单显示 id 而不是 DisplayExpr【英文标题】:DevExtreme dxGrid lookup column form display id instead of DisplayExpr 【发布时间】:2018-09-03 07:18:33 【问题描述】:

我正在使用 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 站点中,他们说这个问题是因为类型不匹配。 我附上了一张显示问题的图片。

【问题讨论】:

如果我没记错的话,您还必须在 Lookup 中添加列才能使其正常工作。 User.DepartmentId 和 Department.DepartmentId 的类型是什么。听起来这两者之间可能存在类型不匹配。 【参考方案1】:

首先你的示例代码有一些问题,你的DepartmentsApiController继承自Controller但返回Ok(),它应该继承自ApiController 相反,第二,您的 GetDepartment 操作返回一个 IActionResult,它应该返回一个 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));
  

【讨论】:

谢谢,我只是将 GetDepartment 方法改成采用 DataSourceLoadOptions oadOptions 就可以了

以上是关于DevExtreme dxGrid 查找列表单显示 id 而不是 DisplayExpr的主要内容,如果未能解决你的问题,请参考以下文章

text devextreme中的查找方法

DevExpress v17.2新功能预告改进DevExtreme编辑器

具有服务器端分页/排序的 DevExtreme 数据网格不适用于过滤

使用 Angular2 DevExtreme 显示和隐藏表单元素

未从 CDN 显示 devextreme 组件的图标

Angular Devextreme - 获取当前页面上的总行数