【发布时间】:2016-05-02 13:57:56
【问题描述】:
我有一个项目,我在其中使用 KendoUI Grid,使用服务器而不是本地获取数据。
我不确定我的服务器应该提供什么 JSON 响应才能使分组工作。我的目标是当用户将一列拖到分组标题时,我知道要返回什么样的 JSON 响应,以便 GRID 按该列和可能添加到该标题的任何其他列进行分组。
鉴于上图,我如何创建一个 JSON 响应来实现它(因此它显示了它应该分组的内容)? 我知道我必须自己在服务器上执行此操作,但不确定 JSON 需要如何格式化。此外,如果我想在创建组时在组旁边显示一个“计数”字段,以便我知道每个组中有多少项目(我认为这是汇总?)
我当前的网格代码如下所示:
<div id="grid" style="height:100%;"></div>
<script>
$(window).on("resize", function() {
kendo.resize($("#grid"));
});
var crudServiceBaseUrl = "/api",
dataSource = new kendo.data.DataSource({
transport: {
read: {
url: crudServiceBaseUrl + "/companies",
dataType: "json",
type: "POST"
},
update: {
url: crudServiceBaseUrl + "/companies/update",
dataType: "json",
type: "POST"
},
destroy: {
url: crudServiceBaseUrl + "/companies/destroy",
dataType: "json",
type: "POST"
},
create: {
url: crudServiceBaseUrl + "/companies/create",
dataType: "json",
type: "POST"
},
parameterMap: function(options, operation) {
if (operation !== "read" && options.models) {
return {models: kendo.stringify(options.models)};
}
}
},
error: function (e) {
/* the e event argument will represent the following object:
{
errorThrown: "custom error",
errors: ["foo", "bar"]
sender: {... the Kendo UI DataSource instance ...}
status: "customerror"
xhr: null
}
*/
//alert("Status: " + e.status + "; Error message: " + e.errorThrown);
console.log("Status: " + e.status + "; Error message: " + e.errorThrown);
console.log("Errors: " + e.errors.join("; "));
},
autoSync: false,
serverPaging: true,
serverFiltering: true,
serverSorting: true,
serverGrouping: true,
serverAggregates: true,
pageSize: 20,
columnResizeHandleWidth: 6,
schema: {
total: "itemCount",
data: "items",
groups: "groups",
aggregates: "aggregates",
group: {
field: "phone", aggregates: [{ field: "phone", aggregate: "count" }]
},
model: {
id: "id",
fields: {
id: { editable: false, nullable: true },
name: { validation: { required: true } },
phone: {
type: "string",
validation: {
required: true,
phonerule: function(e){
if (e.is("[data-phonerule-msg]"))
{
var input = e.data('kendoMaskedTextBox');
//If we reached the end of input then it will return -1 which means true, validation passed
//Otherwise it won't === -1 and return false meaning all the characters were not entered.
return input.value().indexOf(input.options.promptChar) === -1;
}
return true; //return true for anything else that is not data-phonerule-msg
}
}
},
email: { type: "string", validation: { required: true, email:true } }
}
}
}
});
$("#grid").kendoGrid({
dataSource: dataSource,
groupable: true,
sortable: {
mode: "multiple",
allowUnsort: true
},
selectable: "multiple cell",
allowCopy:true,
toolbar: ["create","excel"],
excel: {
fileName: "Kendo UI Grid Export.xlsx",
//Below is only used as fallback for old browsers without support
proxyURL: "//demos.telerik.com/kendo-ui/service/export",
filterable: true
},
pageable: {
refresh: true,
pageSizes: true,
buttonCount: 5
},
reorderable: true,
resizable: true,
columnMenu: true,
filterable: true,
editable: "popup",
mobile: true,
columns: [
{
field: "name",
title: "Company Name",
aggregates: ["count"],
groupFooterTemplate: "Count: #=count#"
},
{
field: "phone",
title: "Phone",
editor: function(container, options){
//pattern="[(][0-9]{3}[)] [0-9]{3}-[0-9]{4}"
var input = $('<input type="tel" data-phonerule-msg="Invalid Phone Number!" class="k-textbox" required />');
input.attr("name", options.field);
input.kendoMaskedTextBox({
mask: "(999) 000-0000"
});
input.appendTo(container);
},
aggregates: ["count"],
groupFooterTemplate: "Count: #=count#"
},
{
field: "email",
title: "Email",
editor: function(container, options){
var input = $('<input type="email" data-email-msg="Invalid email!" class="k-textbox" required/>');
input.attr("name", options.field);
input.appendTo(container);
},
aggregates: ["count"],
groupFooterTemplate: "Count: #=count#"
},
{
command: ["edit", "destroy"],
title: "Operations",
width: "240px"
}
],
});
</script>
我当前通过 Symfony 3.0 生成演示 javascript 的代码如下。
DefaultController.php
/**
* @Route("/api/companies", name="api_companies_read")
*/
public function apiCompaniesReadAction(Request $request)
{
$data["itemCount"] = "7";
// $tdata["field"] = "";
// $tdata["value"] = "";
// $tdata["items"] = "hey";
// $data["groups"][] = $tdata;
$tdata["id"] = "1";
$tdata["name"] = "Joe";
$tdata["phone"] = "(714)475-8651";
$tdata["email"] = "Joe@whatever.com";
$data["items"][] = $tdata;
$tdata["id"] = "2";
$tdata["name"] = "Rachel";
$tdata["phone"] = "(563)812-4184";
$tdata["email"] = "rachel@yahoo.com";
$data["items"][] = $tdata;
$tdata["id"] = "3";
$tdata["name"] = "John";
$tdata["phone"] = "(563)812-4184";
$tdata["email"] = "John@yahoo.com";
$data["items"][] = $tdata;
$tdata["id"] = "4";
$tdata["name"] = "Richard";
$tdata["phone"] = "(563)812-4184";
$tdata["email"] = "John@yahoo.com";
$data["items"][] = $tdata;
$tdata["id"] = "5";
$tdata["name"] = "Sister";
$tdata["phone"] = "(563)812-4184";
$tdata["email"] = "John@yahoo.com";
$data["items"][] = $tdata;
$tdata["id"] = "6";
$tdata["name"] = "Brother";
$tdata["phone"] = "(563)812-4184";
$tdata["email"] = "Brother@yahoo.com";
$data["items"][] = $tdata;
$tdata["id"] = "7";
$tdata["name"] = "Sibling";
$tdata["phone"] = "(563)812-4184";
$tdata["email"] = "Sibling@yahoo.com";
$data["items"][] = $tdata;
// schema: {
// total: "total",
// model: {
// id: "CompanyID",
// fields: {
// CompanyID: { editable: false, nullable: true },
// Name: { validation: { required: true } },
// Phone: { type: "string" },
// Email: { type: "string" }
// }
// }
// }
// replace this example code with whatever you need
return new JsonResponse($data);
}
它创建的当前 JSON 如下所示。
JSON
{"itemCount":"7","items":[{"id":"1","name":"Joe","phone":"(714)475-8651","email":"Joe@whatever.com"},{"id":"2","name":"Rachel","phone":"(563)812-4184","email":"rachel@yahoo.com"},{"id":"3","name":"John","phone":"(563)812-4184","email":"John@yahoo.com"},{"id":"4","name":"Richard","phone":"(563)812-4184","email":"Richard@yahoo.com"},{"id":"5","name":"Sister","phone":"(563)812-4184","email":"Sister@yahoo.com"},{"id":"6","name":"Brother","phone":"(563)812-4184","email":"Brother@yahoo.com"},{"id":"7","name":"Sibling","phone":"(563)812-4184","email":"Sibling@yahoo.com"}]}
我发现一篇文章 here 看起来很接近我想要的,只是很难理解。 This 也可能有帮助。
我创建了JSFiddle 可以玩,只需要提供有效数据。
更新
我让服务器分页工作!第一个主要变化是数据源的传输,您必须更改 parameterMap 以发送 json,以便您可以访问它试图告诉您的服务器进行更改的内容。
dataSource = new kendo.data.DataSource({
transport: {
read: {
url: crudServiceBaseUrl + "/companies",
dataType: "json",
type: "POST"
},
update: {
url: crudServiceBaseUrl + "/companies/update",
dataType: "json",
type: "POST"
},
destroy: {
url: crudServiceBaseUrl + "/companies/destroy",
dataType: "json",
type: "POST"
},
create: {
url: crudServiceBaseUrl + "/companies/create",
dataType: "json",
type: "POST"
},
parameterMap: function(options, operation) {
return kendo.stringify(options);
}
},
我的数据源如上所示,但您可以根据自己的需要进行调整。接下来是我的php文件。
PHP /公司
/**
* @Route("/api/companies", name="api_companies_read")
*/
public function apiCompaniesReadAction(Request $request)
{
$request_body = file_get_contents('php://input');
$json = json_decode($request_body);
//Based on the JSON Payload response adjust the search in the database
if($json){
$page = $json->page;
$pageSize = $json->pageSize;
$skip = $json->skip;
$take = $json->take;
}else{
$page = 1;
$pageSize = 20;
$skip = 1;
$take = 1;
}
$repository = $this->getDoctrine()->getRepository('AppBundle:Company');
/*
findBy(
array $criteria,
array $orderBy = null,
integer|null $limit = null,
integer|null $offset = null
)
*/
$company_total = $repository->findAll();
$company_records = $repository->findBy(array(),array(),$pageSize,($page-1)*$pageSize);
$data["total"] = count($company_total);
foreach($company_records as $company){
$temp["id"] = $company->getId();
$temp["name"] = $company->getName();
$temp["phone"] = $company->getPhone();
$temp["email"] = $company->getEmail();
$data["data"][] = $temp;
}
//converts data to JSON
return new JsonResponse($data);
}
请记住,上面是一个 Symfony 3.0 php 实现,使用注解来设置路由。该代码中的重要部分是。
$request_body = file_get_contents('php://input');
$json = json_decode($request_body);
//Based on the JSON Payload response adjust the search in the database
if($json){
$page = $json->page;
$pageSize = $json->pageSize;
$skip = $json->skip;
$take = $json->take;
}else{
$page = 1;
$pageSize = 20;
$skip = 1;
$take = 1;
}
file_get_contents('php://input'); 获取 KendoUI 控件发回的 javascript 对象。
更新 #3 让服务器排序正常工作!
以下是使用 Symfony 3.0 和 Doctrine 进行服务器排序的示例实现!
PHP
/**
* @Route("/api/companies", name="api_companies_read")
*/
public function apiCompaniesReadAction(Request $request)
{
$request_body = file_get_contents('php://input');
$json = json_decode($request_body);
//print_r($json);
//default parameters in case of error.
$page = 1;
$pageSize = 20;
$skip = 1;
$take = 1;
$sort = array();
//Based on the JSON Payload response adjust the search in the database
if(isset($json)){
$page = $json->page;
$pageSize = $json->pageSize;
$skip = $json->skip;
$take = $json->take;
if(isset($json->sort)){
//"sort":[{"field":"name","dir":"asc"}]}:
foreach($json->sort as $sortObj){
$sort[$sortObj->field] = $sortObj->dir;
}
}
}
$repository = $this->getDoctrine()->getRepository('AppBundle:Company');
/*
findBy(
array $criteria,
array $orderBy = null,
integer|null $limit = null,
integer|null $offset = null
)
*/
$company_total = $repository->findAll();
$company_records = $repository->findBy(array(),$sort,$pageSize,($page-1)*$pageSize);
$data["total"] = count($company_total);
foreach($company_records as $company){
$temp["id"] = $company->getId();
$temp["name"] = $company->getName();
$temp["phone"] = $company->getPhone();
$temp["email"] = $company->getEmail();
$data["data"][] = $temp;
}
//converts data to JSON
return new JsonResponse($data);
}
【问题讨论】:
-
有人有什么想法吗?
标签: json kendo-ui telerik kendo-grid telerik-grid