前言

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,实体类的定义如下:

/**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\Column(type="string",length=100)
     */
    protected $name;

    /**
     * @ORM\Column(type="decimal",scale=2)
     */
    protected $price;

    /**
     * @ORM\Column(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');
						},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 }

Symfony2.x + EasyUI datagrid Ajax方式实现数据交互的更多相关文章

  1. canvas中普通动效与粒子动效的实现代码示例

    canvas用于在网页上绘制图像、动画,可以将其理解为画布,在这个画布上构建想要的效果。本文详细的介绍了粒子特效,和普通动效进行对比,非常具有实用价值,需要的朋友可以参考下

  2. H5混合开发app如何升级的方法

    本篇文章主要介绍了H5混合开发app如何升级的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  3. canvas学习和滤镜实现代码

    这篇文章主要介绍了canvas学习和滤镜实现代码,利用 canvas,前端人员可以很轻松地、进行图像处理,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  4. localStorage的过期时间设置的方法详解

    这篇文章主要介绍了localStorage的过期时间设置的方法详解的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  5. 详解HTML5 data-* 自定义属性

    这篇文章主要介绍了详解HTML5 data-* 自定义属性的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  6. HTML5的postMessage的使用手册

    HTML5提出了一个新的用来跨域传值的方法,即postMessage,这篇文章主要介绍了HTML5的postMessage的使用手册的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  7. 教你使用Canvas处理图片的方法

    本篇文章主要介绍了教你使用Canvas处理图片的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  8. iOS:用于填充异步提取数据的设计模式

    我正在开发一个从Web获取数据并将其显示给用户的应用程序.假设数据是餐馆的评论,并且在一个视图上显示一个评论.用户可以向左或向右滑动以转到上一个/下一个评论.数据是异步提取的.这是问题陈述–假设已经提取了5条评论,并且用户正在查看当前的第3条评论.现在,第6次审核被提取,我想将其显示为用户的第4次审核.我的模型类应该如何通知视图控制器?除上述3之外的其他建议值得欢迎!

  9. ios – 1天后firebase crashlytics报告中没有数据

    解决方法对于那些仍然有问题的人.检查您的podfile中是否还有pod’Firebase/Crash’.当我删除旧的Firebase崩溃报告时,我的问题已修复.

  10. 将AWS DynamoDB表中的数据加载到iOS上的UITableView

    我的iOS应用程序中使用Swift编写的一个屏幕是UITableView.在这个UITableView中,我想从AWSDynamoDB表中加载名为Books的数据.目前,这是我在故事板上的原型单元格:在表格中我有3个属性:“名称”,“价格”和“ISBN”.我想要的是扫描“书籍”表,并过滤结果,因此结果的“ISBN”属性将包含数字“9”.在我筛选结果后,我想将它们应用到UITableView,因此“

随机推荐

  1. xe-ajax-mock 前端虚拟服务

    最新版本见Github,点击查看历史版本基于XEAjax扩展的Mock虚拟服务插件;对于前后端分离的开发模式,ajax+mock使前端不再依赖后端接口开发效率更高。CDN使用script方式安装,XEAjaxMock会定义为全局变量生产环境请使用xe-ajax-mock.min.js,更小的压缩版本,可以带来更快的速度体验。

  2. vue 使用 xe-ajax

    安装完成后自动挂载在vue实例this.$ajaxCDN安装使用script方式安装,VXEAjax会定义为全局变量生产环境请使用vxe-ajax.min.js,更小的压缩版本,可以带来更快的速度体验。cdnjs获取最新版本点击浏览已发布的所有npm包源码unpkg获取最新版本点击浏览已发布的所有npm包源码AMD安装require.js安装示例ES6Module安装通过Vue.use()来全局安装示例./Home.vue

  3. AJAX POST数据中文乱码解决

    前端使用encodeURI进行编码后台java.net.URLDecoder进行解码编解码工具

  4. Koa2框架利用CORS完成跨域ajax请求

    实现跨域ajax请求的方式有很多,其中一个是利用CORS,而这个方法关键是在服务器端进行配置。本文仅对能够完成正常跨域ajax响应的,最基本的配置进行说明。这样OPTIONS请求就能够通过了。至此为止,相当于仅仅完成了预检,还没发送真正的请求呢。

  5. form提交时,ajax上传文件并更新到&lt;input&gt;中的value字段

  6. ajax的cache作用

    filePath="+escape;},error:{alert;}});解决方案:1.加cache:false2.url加随机数正常代码:网上高人解读:cache的作用就是第一次请求完毕之后,如果再次去请求,可以直接从缓存里面读取而不是再到服务器端读取。

  7. 浅谈ajax上传文件属性contentType = false

    默认值为contentType="application/x-www-form-urlencoded".在默认情况下,内容编码类型满足大多数情况。在这里,我们主要谈谈contentType=false.在使用ajax上传文件时:在其中先封装了一个formData对象,然后使用post方法将文件传给服务器。说到这,我们发现在JQueryajax()方法中我们使contentType=false,这不是冲突了吗?这就是因为当我们在form标签中设置了enctype=“multipart/form-data”,

  8. 909422229_ajaxFileUpload上传文件

    ajaxFileUpload.js很多同名的,因为做出来一个很容易。我上github搜AjaxFileUpload出来很多类似js。ajaxFileUpload是一个异步上传文件的jQuery插件传一个不知道什么版本的上来,以后不用到处找了。语法:$.ajaxFileUploadoptions参数说明:1、url上传处理程序地址。2,fileElementId需要上传的文件域的ID,即的ID。3,secureuri是否启用安全提交,默认为false。4,dataType服务器返回的数据类型。6,error

  9. AJAX-Cache:一款好用的Ajax缓存插件

    原文链接AJAX-Cache是什么Ajax是前端开发必不可少的数据获取手段,在频繁的异步请求业务中,我们往往需要利用“缓存”提升界面响应速度,减少网络资源占用。AJAX-Cache是一款jQuery缓存插件,可以为$.ajax()方法扩展缓存功能。

  10. jsf – Ajax update/render在已渲染属性的组件上不起作用

    我试图ajax更新一个有条件渲染的组件。我可以确保#{user}实际上是可用的。这是怎么引起的,我该如何解决呢?必须始终在ajax可以重新呈现之前呈现组件。Ajax正在使用JavaScriptdocument.getElementById()来查找需要更新的组件。但是如果JSF没有将组件放在第一位,那么JavaScript找不到要更新的内容。解决方案是简单地引用总是渲染的父组件。

返回
顶部