Kendo 可排序/集成 - 网格 - 特定刷新后不排序
Kendo Sortable / Integration - Grid - Not ordering after specific refresh
我有一个 Kendo 网格,按照下面的代码
@(Html.Kendo().Grid<ReportCompetencyViewModel>()
.Name("listGrid")
.BindTo(Model.ReportCompetency.OrderBy(x => x.DisplayOrder))
.Columns(columns =>
{
columns.Bound(c => c.Code).ClientHeaderTemplate("Code");
columns.Bound(c => c.DisplayName).ClientHeaderTemplate("Description");
columns.Bound(c => c.IEC).ClientHeaderTemplate("IEC");
columns.Bound(c => c.Active)
.ClientTemplate("#if(Active) {# <i class='fas fa-check'></i> # } else {# <i class='fas fa-times'></i> #} #")
.ClientHeaderTemplate("Active")
.HtmlAttributes(new { @class = "text-center" })
.Width(100);
})
.Pageable(pageable => pageable
.Refresh(true)
.PageSizes(true)
.ButtonCount(5))
.Sortable()
.Filterable()
.Groupable()
.NoRecords(n => n.Template("<p>There are no records to display.</p>"))
.HtmlAttributes(new { style = "width:100%;" })
.Selectable(selectable => selectable
.Mode(GridSelectionMode.Single)
.Type(GridSelectionType.Row))
.Events(events => events
.Change("lu.onChange")
)
.Pageable(p =>
{
p.PageSizes(new[] { 5, 10, 30, 50, 100 });
})
.DataSource(dataSource => dataSource
.Ajax()
.Group(g => g.Add(x => x.IEC))
.PageSize(50)
.ServerOperation(false)
.Read(r => r.Action("RefreshCompetenciesGridData", "ReportLookup").Data("lu.sendAntiForgery"))
)
)
我有一个部分,其中也有一个可排序的元素,如下所示。
@(Html.Kendo().Sortable()
.For($"#{@Model.GridId}")
.Filter("table > tbody > tr")
.Cursor("move")
.PlaceholderHandler("sg.placeholder")
.ContainerSelector($"#{Model.GridId} tbody")
.Events(events => events.Change("sg.onChange"))
)
onchange 事件是
onChange = (e: any) => {
var grid: kendo.ui.Grid = $("#" + this.gridId).data("kendoGrid"),
skip = grid.dataSource.skip(),
oldIndex = e.oldIndex + skip,
newIndex = e.newIndex + skip,
data = grid.dataSource.data(),
dataItem = grid.dataSource.getByUid(e.item.data("uid"));
grid.dataSource.remove(dataItem);
grid.dataSource.insert(newIndex, dataItem);
console.log(newIndex);
if (this.showSaveNotification && $("#" + this.warningDivId).length) {
$("#" + this.warningDivId).slideDown();
this.showSaveNotification = false;
}
}
可排序元素在大多数情况下效果很好。
执行重新排序时,打开 kendo window 并执行保存操作,网格将根据以下代码使用 TypeScript class 中的更新数据进行刷新。
save = (model: any) => {
var _self = this;
var girdOrderArray = new Array();
if ($("#grid-reorder-warning").length && $("#grid-reorder-warning").is(":visible")) {
var grid = $("#" + this.girdName).data("kendoGrid");
var dataItems = grid.dataItems() as any;
$.each(dataItems,
(idx: number, dataItem) => {
var di = idx + 1;
var id = dataItem.id === undefined ? dataItem.Id : dataItem.id; // Changing the display order appears to also change the dataItem from Id to id.
girdOrderArray.push({ Id: id, DisplayOrder: di });
});
}
var da = new Tmsp.AjaxDataAccessLayer(Tmsp.Enums.AjaxCallType.Post,
Tmsp.Enums.AjaxDataType.Json,
this.saveUrl,
JSON.stringify(model),
"application/json; charset=utf-8",
{ "RequestVerificationToken": $('input[name="__RequestVerificationToken"]').val() },
true, true);
da.ajaxCall(data => {
_self.closeWindow();
if ($("#grid-reorder-warning").is(":visible")) {
grid.dataSource.read().then(() => {
var dataItems = grid.dataItems();
var arr = new Array() as any;
$.each(dataItems,
(idx, dataItem: any) => {
var id = dataItem.Id === null ? dataItem.id : dataItem.Id;
var gridOrderObj = jQuery.grep(girdOrderArray,
function (gridOrderObj: any) { return gridOrderObj.Id == id });
dataItem.set("DisplayOrder", gridOrderObj[0].DisplayOrder);
});
grid.dataSource.sort({ field: "DisplayOrder", dir: "Desc" });
});
} else {
_self.refreshGrid();
}
return false;
}, (xhr, status, errorThrown) => {
console.log(xhr);
console.log(status);
console.log(errorThrown);
});
return false;
}
这会保存网格,并根据 DisplayOrder 对网格重新排序,这非常好,也是我需要的。但是,当我在此之后尝试重新排序任何其他内容时,重新排序的项目为我提供了新索引,但实际上并没有在网格上更改。
但是,如果我通过其他方式刷新网格,则重新排序效果很好。
所以,我的问题是,我需要保持保存前的显示顺序,我该如何实现。
我尝试过的东西
- 正在更新刷新的网格上的显示顺序 - 怀疑是问题的原因。
- 创建了一个新控制器 returns 部分并再次初始化控件 - 无效
- 重置特定的 uid(不是首选选项,但我想我会尝试看看它是否是 uid)。 - 无效果
啊哈!!!
我找到了答案,而 Telerik 并不容易找到如何做事。
使用我在这里 link https://docs.telerik.com/kendo-ui/controls/interactivity/sortable/how-to/persist-order-in-localstorage 我已经能够找到我需要的代码来保持状态。
我相信我上周的一次尝试虽然不完美,但实际上我已经很接近了。
这是 on change 事件现在的样子
onChange = (e: any) => {
var grid: kendo.ui.Grid = $("#" + this.gridId).data("kendoGrid"),
skip = grid.dataSource.skip(),
oldIndex = e.oldIndex + skip,
newIndex = e.newIndex + skip,
data = grid.dataSource.data(),
dataItem = grid.dataSource.getByUid(e.item.data("uid"));
grid.dataSource.remove(dataItem);
grid.dataSource.insert(newIndex, dataItem);
console.log(newIndex);
localStorage.setItem("sortableData", kendo.stringify(data)); //set the updated in local storage
if (this.showSaveNotification && $("#" + this.warningDivId).length) {
$("#" + this.warningDivId).slideDown();
this.showSaveNotification = false;
}
}
这里的新行是
localStorage.setItem("sortableData", kendo.stringify(data)); //set the updated in local storage
新的保存和刷新网格看起来像这样
saveNewOrder = () => {
var model = new Array();
var grid: kendo.ui.Grid = $("#" + this.gridId).data("kendoGrid");
var _self = this;
var dataItems = grid.dataItems() as any;
$.each(dataItems,
(idx : number, dataItem) => {
var di = idx + 1;
var id = dataItem.Id === null ? dataItem.id : dataItem.Id;
model.push({ Id: id , DisplayOrder: di});
});
var da = new AjaxDataAccessLayer(Tmsp.Enums.AjaxCallType.Put,
Tmsp.Enums.AjaxDataType.Json,
this.saveUrl,
JSON.stringify(model),
"application/json; charset=utf-8",
{ "RequestVerificationToken": $('input[name="__RequestVerificationToken"]').val() },
true,
true);
da.ajaxCall(data =>{
_self.refreshGridOrder();
}, (xhr, textStatus, errorThrown) => {
////console.log(xhr);
////console.log(textStatus);
////console.log(errorThrown);
});
}
refreshGridOrder = () => {
var grid = $("#" + this.gridId).data("kendoGrid");
grid.dataSource.read().then(() => {
var data = JSON.parse(localStorage.getItem("sortableData"));
grid.dataSource.data(data);
$("#" + this.warningDivId).slideUp();
this.showSaveNotification = true;
});
}
另一件要记住的事情是,因为这是从多个位置使用的,所以还要在文档准备好时清除本地存储。
我有一个 Kendo 网格,按照下面的代码
@(Html.Kendo().Grid<ReportCompetencyViewModel>()
.Name("listGrid")
.BindTo(Model.ReportCompetency.OrderBy(x => x.DisplayOrder))
.Columns(columns =>
{
columns.Bound(c => c.Code).ClientHeaderTemplate("Code");
columns.Bound(c => c.DisplayName).ClientHeaderTemplate("Description");
columns.Bound(c => c.IEC).ClientHeaderTemplate("IEC");
columns.Bound(c => c.Active)
.ClientTemplate("#if(Active) {# <i class='fas fa-check'></i> # } else {# <i class='fas fa-times'></i> #} #")
.ClientHeaderTemplate("Active")
.HtmlAttributes(new { @class = "text-center" })
.Width(100);
})
.Pageable(pageable => pageable
.Refresh(true)
.PageSizes(true)
.ButtonCount(5))
.Sortable()
.Filterable()
.Groupable()
.NoRecords(n => n.Template("<p>There are no records to display.</p>"))
.HtmlAttributes(new { style = "width:100%;" })
.Selectable(selectable => selectable
.Mode(GridSelectionMode.Single)
.Type(GridSelectionType.Row))
.Events(events => events
.Change("lu.onChange")
)
.Pageable(p =>
{
p.PageSizes(new[] { 5, 10, 30, 50, 100 });
})
.DataSource(dataSource => dataSource
.Ajax()
.Group(g => g.Add(x => x.IEC))
.PageSize(50)
.ServerOperation(false)
.Read(r => r.Action("RefreshCompetenciesGridData", "ReportLookup").Data("lu.sendAntiForgery"))
)
)
我有一个部分,其中也有一个可排序的元素,如下所示。
@(Html.Kendo().Sortable()
.For($"#{@Model.GridId}")
.Filter("table > tbody > tr")
.Cursor("move")
.PlaceholderHandler("sg.placeholder")
.ContainerSelector($"#{Model.GridId} tbody")
.Events(events => events.Change("sg.onChange"))
)
onchange 事件是
onChange = (e: any) => {
var grid: kendo.ui.Grid = $("#" + this.gridId).data("kendoGrid"),
skip = grid.dataSource.skip(),
oldIndex = e.oldIndex + skip,
newIndex = e.newIndex + skip,
data = grid.dataSource.data(),
dataItem = grid.dataSource.getByUid(e.item.data("uid"));
grid.dataSource.remove(dataItem);
grid.dataSource.insert(newIndex, dataItem);
console.log(newIndex);
if (this.showSaveNotification && $("#" + this.warningDivId).length) {
$("#" + this.warningDivId).slideDown();
this.showSaveNotification = false;
}
}
可排序元素在大多数情况下效果很好。
执行重新排序时,打开 kendo window 并执行保存操作,网格将根据以下代码使用 TypeScript class 中的更新数据进行刷新。
save = (model: any) => {
var _self = this;
var girdOrderArray = new Array();
if ($("#grid-reorder-warning").length && $("#grid-reorder-warning").is(":visible")) {
var grid = $("#" + this.girdName).data("kendoGrid");
var dataItems = grid.dataItems() as any;
$.each(dataItems,
(idx: number, dataItem) => {
var di = idx + 1;
var id = dataItem.id === undefined ? dataItem.Id : dataItem.id; // Changing the display order appears to also change the dataItem from Id to id.
girdOrderArray.push({ Id: id, DisplayOrder: di });
});
}
var da = new Tmsp.AjaxDataAccessLayer(Tmsp.Enums.AjaxCallType.Post,
Tmsp.Enums.AjaxDataType.Json,
this.saveUrl,
JSON.stringify(model),
"application/json; charset=utf-8",
{ "RequestVerificationToken": $('input[name="__RequestVerificationToken"]').val() },
true, true);
da.ajaxCall(data => {
_self.closeWindow();
if ($("#grid-reorder-warning").is(":visible")) {
grid.dataSource.read().then(() => {
var dataItems = grid.dataItems();
var arr = new Array() as any;
$.each(dataItems,
(idx, dataItem: any) => {
var id = dataItem.Id === null ? dataItem.id : dataItem.Id;
var gridOrderObj = jQuery.grep(girdOrderArray,
function (gridOrderObj: any) { return gridOrderObj.Id == id });
dataItem.set("DisplayOrder", gridOrderObj[0].DisplayOrder);
});
grid.dataSource.sort({ field: "DisplayOrder", dir: "Desc" });
});
} else {
_self.refreshGrid();
}
return false;
}, (xhr, status, errorThrown) => {
console.log(xhr);
console.log(status);
console.log(errorThrown);
});
return false;
}
这会保存网格,并根据 DisplayOrder 对网格重新排序,这非常好,也是我需要的。但是,当我在此之后尝试重新排序任何其他内容时,重新排序的项目为我提供了新索引,但实际上并没有在网格上更改。
但是,如果我通过其他方式刷新网格,则重新排序效果很好。
所以,我的问题是,我需要保持保存前的显示顺序,我该如何实现。
我尝试过的东西
- 正在更新刷新的网格上的显示顺序 - 怀疑是问题的原因。
- 创建了一个新控制器 returns 部分并再次初始化控件 - 无效
- 重置特定的 uid(不是首选选项,但我想我会尝试看看它是否是 uid)。 - 无效果
啊哈!!!
我找到了答案,而 Telerik 并不容易找到如何做事。
使用我在这里 link https://docs.telerik.com/kendo-ui/controls/interactivity/sortable/how-to/persist-order-in-localstorage 我已经能够找到我需要的代码来保持状态。
我相信我上周的一次尝试虽然不完美,但实际上我已经很接近了。
这是 on change 事件现在的样子
onChange = (e: any) => {
var grid: kendo.ui.Grid = $("#" + this.gridId).data("kendoGrid"),
skip = grid.dataSource.skip(),
oldIndex = e.oldIndex + skip,
newIndex = e.newIndex + skip,
data = grid.dataSource.data(),
dataItem = grid.dataSource.getByUid(e.item.data("uid"));
grid.dataSource.remove(dataItem);
grid.dataSource.insert(newIndex, dataItem);
console.log(newIndex);
localStorage.setItem("sortableData", kendo.stringify(data)); //set the updated in local storage
if (this.showSaveNotification && $("#" + this.warningDivId).length) {
$("#" + this.warningDivId).slideDown();
this.showSaveNotification = false;
}
}
这里的新行是
localStorage.setItem("sortableData", kendo.stringify(data)); //set the updated in local storage
新的保存和刷新网格看起来像这样
saveNewOrder = () => {
var model = new Array();
var grid: kendo.ui.Grid = $("#" + this.gridId).data("kendoGrid");
var _self = this;
var dataItems = grid.dataItems() as any;
$.each(dataItems,
(idx : number, dataItem) => {
var di = idx + 1;
var id = dataItem.Id === null ? dataItem.id : dataItem.Id;
model.push({ Id: id , DisplayOrder: di});
});
var da = new AjaxDataAccessLayer(Tmsp.Enums.AjaxCallType.Put,
Tmsp.Enums.AjaxDataType.Json,
this.saveUrl,
JSON.stringify(model),
"application/json; charset=utf-8",
{ "RequestVerificationToken": $('input[name="__RequestVerificationToken"]').val() },
true,
true);
da.ajaxCall(data =>{
_self.refreshGridOrder();
}, (xhr, textStatus, errorThrown) => {
////console.log(xhr);
////console.log(textStatus);
////console.log(errorThrown);
});
}
refreshGridOrder = () => {
var grid = $("#" + this.gridId).data("kendoGrid");
grid.dataSource.read().then(() => {
var data = JSON.parse(localStorage.getItem("sortableData"));
grid.dataSource.data(data);
$("#" + this.warningDivId).slideUp();
this.showSaveNotification = true;
});
}
另一件要记住的事情是,因为这是从多个位置使用的,所以还要在文档准备好时清除本地存储。