在 DataTable 中动态呈现列 - Column.Render 属性
Posted
技术标签:
【中文标题】在 DataTable 中动态呈现列 - Column.Render 属性【英文标题】:Dynamically Render Columns In DataTable - Column.Render Property 【发布时间】:2021-12-08 00:32:49 【问题描述】:我正在开发一个动态数据表,其中数据源是使用 [n] 列动态生成的,其中数据源可能包含 4 列或 6 列作为示例。根据 DataTables 论坛 (How to Render Columns from a dynamic data source) 上的这篇文章,可以定义和构建列定义的变量,并将其传递给初始化。
基于此,我创建了以下代码,该代码适用于给定目的,并根据数据源动态呈现列。
html:
<div class="data-table">
<table id="dataTable" class="table table-striped table-bordered" style="width:100%;"></table>
</div>
脚本:
<script>
var dataToSend = ;
var dataTable;
dataToSend =
"regionId": @Model.RegionId
// Get Column Defintions
var dtColumns = @Html.Raw(Json.`enter code here`Serialize(listOfDefintions));
// DataTable
$(function ()
dataTable =
dt: null,
init: function ()
dt = $("#dataTable").DataTable(
ajax:
type: "GET",
url: "@Url.Action("GetDataForGrid", "Contact")",
data: function ()
return dataToSend;
,
datatype: "json",
dataSrc: ""
,
columns: dtColumns,
lengthMenu: [[10, 25, 50, 100], [10, 25, 50, 100]],
);
,
refresh: function ()
dt.ajax.reload();
dataTable.init();
);
</script>
上面的代码根据下面的数据源渲染了下面的DataTable。
数据源:
渲染表:
我的问题是关于表格的最后一列空的,我需要在其中呈现一个按钮。如果我一直想渲染一个具有已知列值的表,我通常会按照下面的代码行编写一些东西,我将在其中使用 DataTable 属性 column.Render。正如您在下面看到的,使用列的 data 属性,我可以使用创建函数来呈现一个按钮,该按钮可用于快速导航到 Contact/Edit 页面,将“id”作为 Url 路由值传递,意思是可以编辑所选联系人的具体详细信息。
<script>
var dataToSend = ;
var contactDataTable;
dataToSend =
"regionId": @Model.RegionId
;
$(function ()
contactDataTable =
dt: null,
init: function ()
dt = $('#contact-data-table').DataTable(
ajax:
type: "GET",
url: "@Url.Action("GetDataForGrid", "Contact")",
data: function ()
return dataToSend;
,
datatype: "json",
dataSrc: ""
,
columns: [
"title": "Forename",
"data": "forename",
"searchable": true,
,
"title": "Surname",
"data": "surname",
"searchable": true,
,
"title": "Email",
"data": "email",
"searchable": true
,
"Status":
"status":
"searchable":
,
"title": "Role",
"data": "roleName",
"searchable": true
,
"title": "",
"data": "id",
"searchable": false,
"sortable": false,
"render": function (data, type, full, meta)
var buffer = '<a href="@Url.Action("Edit","Contact")/' + data + '" class="btn btn-sm btn-primary js-action"><i class="far fa-edit"></i></a> '
buffer += '<a href="@Url.Action("Delete", "Contact")/' + data + '" class="btn btn-sm btn-danger js-action"><i class="far fa-trash-alt"></i></a>';
return buffer;
],
columnDefs: [
"width": "15%", "targets": 0 ,
"width": "15%", "targets": 1 ,
"width": "20%", "targets": 2 ,
"width": "15%", "targets": 3 ,
"width": "15%", "targets": 4 ,
"width": "20%", "targets": 5 ,
],
lengthMenu: [[10, 25, 50, 100], [10, 25, 50, 100]],
);
,
refresh: function ()
dt.ajax.reload();
</script>
如果我在将列定义变量传递给我的 DataTable 初始化之前定义和构建列定义变量,如何实现在表中呈现按钮的相同原理?
任何帮助都会很棒。
【问题讨论】:
对不起,我不明白......你似乎在朝着一个好的方向前进,应该可以使用数据变量来构造一个传递 id 的 URL - 那么在哪里有问题吗? 建议:不要使用dataSrc: ""
,而是使用函数:dataSrc: function ( json ) ...
。你可以看到一个例子here。这允许您遍历源 JSON 数据,并向每一行添加一个新对象 - 其中该对象是一个字符串,其中包含您要构建的按钮的 HTML。这相当于您想在列渲染器中使用的逻辑。
@MBaas - 在提供的示例中,我希望在表格的最后一列中呈现一个按钮,但在实际呈现 HTML 元素时遇到了困难。在我解决这个问题的各种迭代中,我要么能够呈现一个按钮,但不能访问列的数据属性,在这种情况下是 Id,反之亦然。
我已经能够同时解决这个问题,如果需要我会很乐意发布。我可以按照 andrewJames 的建议来解决这个问题,但是我发现只需将最后一列的 Data 属性设置为 null,并使用 defaultContent 来呈现一个简单的按钮效果很好。然后,我开发了一个点击事件,它获取了当前行的数据,我可以在其中访问 Id 属性以在我的 URL 的构造中使用。很可能有更好的方法,在这种情况下,我将寻求实施。
这是一个很好、直接的解决方案。欢迎您answer your own question - 如果您愿意,您也可以接受它。这将有助于未来的访问者解决这个问题。
【参考方案1】:
给定问题的简单解决方案是使用Column.defaultContent
属性和自定义onClick
事件,可用于构造所需的相关URL。
在下面的示例中,我修改了我的dtColumns
数组,如提供的图像所示,以便相关对象包含defaultContent
的定义,设置为将呈现简单按钮的字符串。要让DataTable
使用defaultContent
,您必须将Data
属性设置为null。
DataTable - 数据源
var myColumnDefs = [
title: "Forename", data: "forename", width: "15%",
title: "Surname", data: "surname", width: "15%",
title: "Email", data: "email", width: "20%",
title: "Status", data: "status", width: "15%",
title: "Role", data: "roleName", width: "15%",
title: "", data: "(string)null", width: "20%", searchable: false, sortable: false, defaultContent: "<a id='btnEdit' class='btn btn-sm btn-primary js-action'><i class='fas fa-edit'></i></a>"
]
这样做会呈现如下表:
修改后的代码实际上只包含额外的函数来处理按钮的onClick
事件。在这种情况下,我可以使用$("#dataTable").DataTable().row((selectedRow).parents("tr")).data()
获取加载记录的数据,其中id属性可以访问。使用这个 Id 值,我能够构建所需的 URL,该 URL 恰好被传递到呈现 Bootstrap 模式的函数中。
<script>
var dataToSend = ;
var dataTable;
// Set Data To Send
dataToSend =
"regionId": "@Model.RegionId"
// Get Column Defintions
var dtColumns = @Html.Raw(Json.Serialize(listOfDefintions));
// DataTable
$(function ()
dataTable =
dt: null,
init: function ()
dt = $("#dataTable").DataTable(
ajax:
type: "GET",
url: "@Url.Action("GetDataForGrid", "Contact")",
data: function ()
return dataToSend;
,
datatype: "json",
dataSrc: ""
,
columns: dtColumns,
lengthMenu: [[10, 25, 50, 100], [10, 25, 50, 100]],
);
,
refresh: function ()
dt.ajax.reload();
dynaGridDataTable.init();
// DataTable Buttons
$("#dataTable").on("click", ".js-action", function (event)
var btnId = $(this).attr("id");
var recordId = getRecordId($(this));
if (btnId !== undefined && btnId == "btnEdit")
// Create Edit URL
var href = '@Url.Action("Popup", "DynaGrid")?appGridName=@Model.AppGrid.GridName&masterRecordId=@Model.AppGrid.MasterRecordFKId&id=' + recordId + '';
renderModalForDataTableButton(href);
else if (btnId !== undefined && btnId == "btnDelete")
// Code
else
alert("Something Went Wrong - Unable To Redirect");
);
// Get Record Id Of Current Row
function getRecordId(selectedRow)
var data = $("#dataTable").DataTable().row((selectedRow).parents("tr")).data();
return data.id;
function renderModalForDataTableButton(href)
$.get(href, function (data)
$('#myModalContent').html(data);
$('#myModal').modal('show');
);
);
</script>
【讨论】:
请选择输入代码、日志等而不是截图。这使得它对许多用户来说更具可读性,并且可以被搜索引擎机器人索引。以上是关于在 DataTable 中动态呈现列 - Column.Render 属性的主要内容,如果未能解决你的问题,请参考以下文章
“未找到记录”不考虑有条件呈现的 p:dataTable 列