Symfony2.x + EasyUI datagrid Ajax方式實現(xiàn)數(shù)據(jù)交互
來源:程序員人生 發(fā)布時間:2014-09-26 16:30:36 閱讀次數(shù):6825次
前言
EasyUI 中的控件大多采用JSON數(shù)據(jù)格式與后臺交互,如果不使用Web應(yīng)用程序沒有使用任何框架,則可以將后臺處理的PHP代碼寫成單獨(dú)的函數(shù),具體實現(xiàn)參考 PHP
- EasyUI DataGrid資料存的方式。如果使用Symfony框架則直接 echo $data 或 echo json_encode()的方式來傳遞數(shù)據(jù)就不行了,因為echo是輸出到屏幕,而Symfony中動作(Action)的返回結(jié)果一般是Response的對象。若果你將要傳遞的數(shù)據(jù)$data以這樣的形式:
return new Response(json_encode($data));
來傳遞,會得到一個只顯示字符的網(wǎng)頁。因為你在Response()中沒有指定模板,返回的字符串將直接作為顯示的內(nèi)容。為了更好地使用EasyUI強(qiáng)大的控件庫,本文通過Ajax方式實現(xiàn)EasyUI的控件與后臺進(jìn)行交互,實現(xiàn)了一個數(shù)據(jù)表的CRUD(增刪改查)操作。
實現(xiàn)過程
Symfony的應(yīng)用程序主要包括:數(shù)據(jù)模型(ORM,每個表都叫一個實體Entity)、控制器(Controller,包括一系列實現(xiàn)具體業(yè)務(wù)的Action,控制器的作用是解析請求,準(zhǔn)備數(shù)據(jù)供模板中展示)、模板(用于展示,Symfony支持twig、XML和PHP等多種實現(xiàn)形式的模板)、路由(一個YML文件,指定一個請求的URL對應(yīng)于那個動作Action)和資源文件。詳細(xì)的介紹參見其他博文。
一、 數(shù)據(jù)模型
數(shù)據(jù)表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實現(xiàn)(可以是XML或PHP實現(xiàn)),與EasyUI DataGrid的Demo代碼非常類似,唯一不同的是Javascript中對數(shù)據(jù)的處理。
默認(rèn)從服務(wù)器傳入的是json格式的數(shù)據(jù),通過調(diào)用DataGrid控件的初始化函數(shù)$('#dg').datagrid()完成數(shù)據(jù)的填充。將DataGrid的數(shù)據(jù)發(fā)給后端采用的ajax方式,其形式為
$.ajax({
type: "POST",
url: "some.php",
data: { name: "John", location: "Boston" }
})
.done(function( msg ) {
alert( "Data Saved: " + msg );
});
具體的使用方法可以參考官網(wǎng):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('確認(rèn)','你確認(rèn)要刪除該項目嗎?',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('對不起,保存數(shù)據(jù)失敗!');
$('#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類)
控制器是具體實現(xiàn)邏輯業(yè)務(wù)的代碼,以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與使用模板的對應(yīng)關(guān)系,本文用到的路由項如下:
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 }
生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈