Symfony2.x + EasyUI datagrid Ajax方式实现数据交互
来源:程序员人生 发布时间:2014-09-26 16:30:36 阅读次数:6267次
前言
EasyUI 中的控件大多采用JSON数据格式与后台交互,如果不使用Web应用程序没有使用任何框架,则可以将后台处理的PHP代码写成单独的函数,具体实现参考 PHP
- EasyUI DataGrid资料存的方式。如果使用Symfony框架则直接 echo $data 或 echo json_encode()的方式来传递数据就不行了,因为echo是输出到屏幕,而Symfony中动作(Action)的返回结果一般是Response的对象。若果你将要传递的数据$data以这样的形式:
return new Response(json_encode($data));
来传递,会得到一个只显示字符的网页。因为你在Response()中没有指定模板,返回的字符串将直接作为显示的内容。为了更好地使用EasyUI强大的控件库,本文通过Ajax方式实现EasyUI的控件与后台进行交互,实现了一个数据表的CRUD(增删改查)操作。
实现过程
Symfony的应用程序主要包括:数据模型(ORM,每个表都叫一个实体Entity)、控制器(Controller,包括一系列实现具体业务的Action,控制器的作用是解析请求,准备数据供模板中展示)、模板(用于展示,Symfony支持twig、XML和PHP等多种实现形式的模板)、路由(一个YML文件,指定一个请求的URL对应于那个动作Action)和资源文件。详细的介绍参见其他博文。
一、 数据模型
数据表Product 有四个字段,id,name,price和description,实体类的定义如下:
/**
* @ORMColumn(type="integer")
* @ORMId
* @ORMGeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORMColumn(type="string", length=100)
*/
protected $name;
/**
* @ORMColumn(type="decimal", scale=2)
*/
protected $price;
/**
* @ORMColumn(type="text")
*/
protected $description;
二、模板
模板使用Symfony推荐的twig实现(可以是XML或PHP实现),与EasyUI DataGrid的Demo代码非常类似,唯一不同的是Javascript中对数据的处理。
默认从服务器传入的是json格式的数据,通过调用DataGrid控件的初始化函数$('#dg').datagrid()完成数据的填充。将DataGrid的数据发给后端采用的ajax方式,其形式为
$.ajax({
type: "POST",
url: "some.php",
data: { name: "John", location: "Boston" }
})
.done(function( msg ) {
alert( "Data Saved: " + msg );
});
具体的使用方法可以参考官网:Ajax API。
本文的模板文件如下:
{% extends 'AcmeStoreBundle::layout.html.twig' %}
{% block content %}
<table id="dg" title="Product List" class="easyui-datagrid" style="width:auto;height:250px"
toolbar="#toolbar" pagination="true"
rownumbers="true" fitColumns="true" singleSelect="true">
<thead>
<tr>
<th data-options="field:'id',width:40,align:'center'">ID</th>
<th data-options="field:'name',width:100,align:'left'">Name</th>
<th data-options="field:'price',width:60,align:'center'">Price</th>
<th data-options="field:'description',width:200,align:'left'">Description</th>
</tr>
</thead>
</table>
<script type="text/javascript" >
$('#dg').datagrid({data:[ {{ products|raw }} ]});
function deleteProduct(){
var row = $('#dg').datagrid('getSelected');
if(row){
$.messager.confirm('确认','你确认要删除该项目吗?',function(r){
if(r){
$.ajax({
type: "POST",
dataType: 'html',
url: "{{ path('product_delete') }}",
data: {
id: row.id,
},
error: function(){
$.messager.show({ // show error message
title: 'Error',
msg: result.errorMsg})},
success: function(data,textStatus,jqXHR){
window.location = '{{ path('product_index') }}';
//alert(data);
}
});//ajax
}//if(r)
});//$message
}else{
$.messager.alert('提示信息:','请先选择您要删除的行?','info');
}// if(row)
}// function deleteProduct()
function editProduct(){
var row = $('#dg').datagrid('getSelected');
if (row){
$('#dlg').dialog('open').dialog('setTitle','Edit Product');
$('#fm').form('load',row);
}else{
$.messager.alert('提示信息:','请先选择您要编辑的行?','info');
}
}
function newProduct(){
$('#dlg').dialog('open').dialog('setTitle','New Product');
$('#fm').form('clear');
}
function saveProduct(){
var raw_str = JSON.stringify($('#fm').serializeArray());
//jstr = "["+jstr+"]";
$('#fm').form('submit',{
onSubmit: function(){
$.ajax({
type: "POST",
dataType: 'json',
url: "{{ path('product_update') }}",
data: {
data_p: raw_str,
},
error: function(){
alert('对不起,保存数据失败!');
$('#dlg').dialog('close');
},
success: function(data,textStatus,jqXHR){
$('#dlg').dialog('close');
window.location = '{{ path('product_index') }}';
//alert(data);
}
});//ajax
}
});
}
</script>
<div id="toolbar">
<a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-add" plain="true" onclick="newProduct()">New Product</a>
<a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-edit" plain="true" onclick="editProduct()">Edit Product</a>
<a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-remove" plain="true" onclick="deleteProduct()">Remove Product</a>
</div>
<div id="dlg" class="easyui-dialog" style="width:400px;height:300px;padding:10px 20px"
closed="true" buttons="#dlg-buttons">
<div class="ftitle">Product Information</div>
<form id="fm" method="post" novalidate>
<div class="fitem">
<label>ID:</label>
<input name="id" readonly="readonly">
</div>
<div class="fitem">
<label>Name:</label>
<input name="name" class="easyui-validatebox" required="true">
</div>
<div class="fitem">
<label>Price:</label>
<input name="price" class="easyui-validatebox" required="true">
</div>
<div class="fitem" >
<label>Description:</label>
<input name="description">
</div>
</form>
</div>
<div id="dlg-buttons">
<a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-ok" onclick="saveProduct()">Save</a>
<a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-cancel" onclick="javascript:$('#dlg').dialog('close')">Cancel</a>
</div>
<style type="text/css">
#fm{
margin:0;
padding:10px 30px;
}
.ftitle{
font-size:14px;
font-weight:bold;
padding:5px 0;
margin-bottom:10px;
border-bottom:1px solid #ccc;
}
.fitem{
margin-bottom:5px;
}
.fitem label{
display:inline-block;
width:80px;
}
</style>
{% endblock %}
三、控制器(Controller类)
控制器是具体实现逻辑业务的代码,以update(更新)和delete(删除)两个操作为例,代码如下:
/**
* @Route("/product/update",name="product_update")
* @Template("AcmeStoreBundle:Product:show.html.twig")
*/
public function updateAction()
{
$request = $this->getRequest();
if ($request->isXmlHttpRequest()) {
//$request_cont = $request->getContent();
// get raw json data
$json_data = $request->request->get('data_p');
$data = json_decode($json_data);
// get properties
$id = $data[0]->{"value"};
$name = $data[1]->{"value"};
$price = $data[2]->{"value"};
$description = $data[3]->{"value"};
// update
$em = $this->getDoctrine()->getEntityManager();
$product = $em->getRepository('AcmeStoreBundle:Product')->find($id);
if(!$product){
//throw $this->createNotFoundException(json_encode('No product found with id ='.$id));
$product = new Product();
$product->setName($name);
$product->setPrice($price);
$product->setDescription($description);
$em->persist($product);
$em->flush();
return new Response(json_encode('create a product with id = '.$product->getId()));
}else{
$product->setName($name);
$product->setPrice(0.0+$price);
$product->setDescription($description);
$em->flush();
return new Response(json_encode('update a product with id = '.$description));
}
}else{
return new Response(json_encode('Illegal request for updating product'),400);
}
}
/**
* @Route("/delete/{id}",name="delete")
* @Template("AcmeStoreBundle:Product:index.html.twig"))
*/
public function deleteAction()
{
$request = $this->getRequest();
if ($request->isXmlHttpRequest()) {
$id = $request->request->get('id');
//$id = 2;
$em = $this->getDoctrine()->getEntityManager();
$product = $em->getRepository('AcmeStoreBundle:Product')
->find($id);
if ($product) {
$em->remove($product);
$em->flush();;
}
return new Response(json_encode('delete'.$id));
}else{
return new Response('Cannot delete it .',400);
}
}
四、路由
路由是建立控制器的Action与使用模板的对应关系,本文用到的路由项如下:
index:
path: /
defaults: { _controller: AcmeStoreBundle:Default:index }
product_index:
path: /product
defaults: { _controller: AcmeStoreBundle:Product:show}
product_show:
pattern: /product/show
defaults: { _controller: AcmeStoreBundle:Product:show}
product_update:
pattern: /product/update
defaults: { _controller: AcmeStoreBundle:Product:update }
product_delete:
pattern: /product/delete
defaults: { _controller: AcmeStoreBundle:Product:delete }
生活不易,码农辛苦
如果您觉得本网站对您的学习有所帮助,可以手机扫描二维码进行捐赠