Kendo 虚拟化没有按预期工作
Kendo Virtualization doesn't work as expected
我正在尝试将列表绑定到我的 kendo 组合框,该列表包含超过 30000 条记录,因此我需要虚拟化功能。我检查了这个文档:
http://docs.telerik.com/kendo-ui/controls/editors/combobox/virtualization#valuemapper
并尝试实现它,但运气不佳。
我的网站API
[Authorize]
[HttpGet]
[Route("app/clients")]
[GzipCompressed]
public IEnumerable<string> GetClients()
{
return businessLayer.GetClients();
}
[Authorize]
[HttpGet]
[Route("app/valuemapper")]
[GzipCompressed]
public int ValueMapper(string value)
{
if (string.IsNullOrWhiteSpace(value))
{
return -1;
}
var clients = businessLayer.GetClients(null);
return clients.ToList().IndexOf(value);
}
businessLayer.GetClients() 将 return 所有 30000 多条记录。
这是我的js
$scope.clientsOptions = {
virtual: {
itemHeight: 26,
valueMapper: function(options) {
$http({
url: config.endpoint + '/app' + '/valuemapper',
method: "GET",
params: {"value": options.value}
}).then(function successResponse(response){
options.success(response.data);
})
}
},
height: 520,
dataSource: getClientDataSource()
}
function getClientDataSource() {
var dataSource = new kendo.data.DataSource({
transport: {
read: function(options) {
$http({
method: 'GET',
url: config.endpoint + '/app' + '/clients',
headers: {
'Content-Type': "application/json",
}
}).then(function successResponse(response) {
options.success(response.data);
});
}
},
pageSize: 80,
serverPaging: true,
serverFiltering: true
});
return dataSource;
}
上面这段代码的问题:
1.分页似乎不起作用,当我在ComboBox中搜索一个字符串时,select它,下次当我点击数组打开组合框时,它会再次调用服务来获取所有数据;
2. 鼠标点击不能select一个select离子,键盘可以用;
有人可以帮忙吗?
更新
您的获取客户端方法未将分页应用于检索到的源
它应该是什么样子:
[Authorize]
[HttpGet]
[Route("app/clients")]
[GzipCompressed]
public ActionResult GetClients([[DataSourceRequest] DataSourceRequest request)
{
return Json(businessLayer.GetClients().ToDataSourceResult(request));
}
发送请求被转换为DataSourceRequest,其中包含服务器分页、过滤、排序等信息。然后将这些信息传递给ToDataSourceResult方法,该方法构建正确的LINQ表达式并检索正确的数据块.
valueMapper 的思想是检索与特定值匹配的行索引。
我很确定您应该在 valueMapper
中将转换后的值发送到您的服务器
$scope.clientsOptions = {
virtual: {
itemHeight: 26,
valueMapper: function(options) {
$http({
url: config.endpoint + '/app' + '/valuemapper',
method: "GET",
//here we convert values before sending
params: convertValues(options.value)
}).then(function successResponse(response){
options.success(response.data);
})
}
},
height: 520,
dataSource: getClientDataSource()
}
function convertValues(value) {
var data = {};
value = $.isArray(value) ? value : [value];
for (var idx = 0; idx < value.length; idx++) {
data["values[" + idx + "]"] = value[idx];
}
return data;
}
这里的 ValueMapper 服务器端示例来自 kendo 个示例 github
https://github.com/telerik/kendo-ui-demos-service/blob/master/KendoCRUDService/Controllers/OrdersController.cs
public ActionResult ValueMapper(int[] values)
{
var indices = new List<int>();
if (values != null && values.Any())
{
var index = 0;
foreach (var order in OrderRepository.All())
{
if (values.Contains(order.OrderID))
{
indices.Add(index);
}
index += 1;
}
}
return this.Jsonp(indices);
}
从 kendo 文档中查看该示例
我正在尝试将列表绑定到我的 kendo 组合框,该列表包含超过 30000 条记录,因此我需要虚拟化功能。我检查了这个文档:
http://docs.telerik.com/kendo-ui/controls/editors/combobox/virtualization#valuemapper
并尝试实现它,但运气不佳。
我的网站API
[Authorize]
[HttpGet]
[Route("app/clients")]
[GzipCompressed]
public IEnumerable<string> GetClients()
{
return businessLayer.GetClients();
}
[Authorize]
[HttpGet]
[Route("app/valuemapper")]
[GzipCompressed]
public int ValueMapper(string value)
{
if (string.IsNullOrWhiteSpace(value))
{
return -1;
}
var clients = businessLayer.GetClients(null);
return clients.ToList().IndexOf(value);
}
businessLayer.GetClients() 将 return 所有 30000 多条记录。
这是我的js
$scope.clientsOptions = {
virtual: {
itemHeight: 26,
valueMapper: function(options) {
$http({
url: config.endpoint + '/app' + '/valuemapper',
method: "GET",
params: {"value": options.value}
}).then(function successResponse(response){
options.success(response.data);
})
}
},
height: 520,
dataSource: getClientDataSource()
}
function getClientDataSource() {
var dataSource = new kendo.data.DataSource({
transport: {
read: function(options) {
$http({
method: 'GET',
url: config.endpoint + '/app' + '/clients',
headers: {
'Content-Type': "application/json",
}
}).then(function successResponse(response) {
options.success(response.data);
});
}
},
pageSize: 80,
serverPaging: true,
serverFiltering: true
});
return dataSource;
}
上面这段代码的问题: 1.分页似乎不起作用,当我在ComboBox中搜索一个字符串时,select它,下次当我点击数组打开组合框时,它会再次调用服务来获取所有数据; 2. 鼠标点击不能select一个select离子,键盘可以用;
有人可以帮忙吗?
更新
您的获取客户端方法未将分页应用于检索到的源
它应该是什么样子:
[Authorize]
[HttpGet]
[Route("app/clients")]
[GzipCompressed]
public ActionResult GetClients([[DataSourceRequest] DataSourceRequest request)
{
return Json(businessLayer.GetClients().ToDataSourceResult(request));
}
发送请求被转换为DataSourceRequest,其中包含服务器分页、过滤、排序等信息。然后将这些信息传递给ToDataSourceResult方法,该方法构建正确的LINQ表达式并检索正确的数据块.
valueMapper 的思想是检索与特定值匹配的行索引。
我很确定您应该在 valueMapper
中将转换后的值发送到您的服务器$scope.clientsOptions = {
virtual: {
itemHeight: 26,
valueMapper: function(options) {
$http({
url: config.endpoint + '/app' + '/valuemapper',
method: "GET",
//here we convert values before sending
params: convertValues(options.value)
}).then(function successResponse(response){
options.success(response.data);
})
}
},
height: 520,
dataSource: getClientDataSource()
}
function convertValues(value) {
var data = {};
value = $.isArray(value) ? value : [value];
for (var idx = 0; idx < value.length; idx++) {
data["values[" + idx + "]"] = value[idx];
}
return data;
}
这里的 ValueMapper 服务器端示例来自 kendo 个示例 github https://github.com/telerik/kendo-ui-demos-service/blob/master/KendoCRUDService/Controllers/OrdersController.cs
public ActionResult ValueMapper(int[] values)
{
var indices = new List<int>();
if (values != null && values.Any())
{
var index = 0;
foreach (var order in OrderRepository.All())
{
if (values.Contains(order.OrderID))
{
indices.Add(index);
}
index += 1;
}
}
return this.Jsonp(indices);
}
从 kendo 文档中查看该示例