This is an article about the use of easyui with ajax. It also introduces the use of angularjs and allows you to feel the power of angularjs. There are a lot of articles about ajax on the Internet. I won't start writing directly from the js of the native httpxmlrequest object. Reading that kind of thing is just to understand how high-level things come from and what the principles are. When you actually do it, write that kind of thing. Isn’t it nonsense? If you take advantage of your skills, you can use that kind of code to write the entire site. Things like html js were not fully thought out when they were first designed, and they are just bullshit. Fortunately, there are various frameworks that can help us make this shit more delicious more easily. Fortunately, due to the promotion of the Internet industry, these things on the browser side are developing in the direction of unified standards.
Let’s create a webform page HelloAjaxNet.aspx. Let’s talk about ajax first. Here I use the AjaxPro.2.dll that is widely circulated on the Internet. His website is http://www.ajaxpro.info/ This is a personal work and it is very easy to use.
Originally, the new asp.net comes with server-side methods declared using the webmethod attribute and client-side pagemethods access methods. Various objects can also be digitized in json, and the functions are the same as above. Microsoft comes with the codebehind of aspx. The code method must be static. As for webconfig, there is no need to configure it in the new version of vs2013 development environment. If it is an old one, create a new ajax website project and the webconfig will be automatically completed. Then the server page is loaded in the ScriptManager. .GetCurrent(Page).EnablePageMethods = true; The client must have the form of runat=server and
I still think the above one is more useful. I won’t say much about its principle. When the page is loaded, the server object is registered, and then the generated html page has a few more sentences
<script type="text/javascript" src="/ajaxpro/prototype.ashx"></script> <script type="text/javascript" src="/ajaxpro/core.ashx"></script> <script type="text/javascript" src="/ajaxpro/converter.ashx"></script> <script type="text/javascript" src="/ajaxpro/WebApplication.StudentsInfo,WebApplication.ashx"></script> <script type="text/javascript" src="/ajaxpro/WebApplication.Grad,WebApplication.ashx"></script> <script type="text/javascript" src="/ajaxpro/WebApplication.NewFolder.HelloAjaxNet,WebApplication.ashx"></script> <script type="text/javascript" src="/ajaxpro/WebApplication.DataEntity,WebApplication.ashx"></script>
Why? It’s to reference a js file ajaxpro/WebApplication1.NewFolder2.HelloAjaxNet,WebApplication1.ashx
Then you will understand that this script for you to call js on the client is automatically generated by the server and has exactly the same name as your server. Then you can call back the server method on the client. There is nothing magical about it. Yes, we mainly want to use this feature and the convenience of json data to achieve seamless transfer of client-server data.
About the serialization of json data. In the past, you could only use external json libraries or Microsoft’s own for manual parsing:
Server:
public string ServerProcerMethod(string stu) { //System.Web.Script.Serialization.JavaScriptSerializer jsSerializer = new System.Web.Script.Serialization.JavaScriptSerializer(); //StuInfo s= jsSerializer.Deserialize<StuInfo>(stu); System.Web.Script.Serialization.JavaScriptSerializer jsSerializer = new System.Web.Script.Serialization.JavaScriptSerializer(); List<StuInfo> s = jsSerializer.Deserialize<List<StuInfo>>(stu); if (s != null && s.Count > ) { StuInfo stu= s[]; StringBuilder sb = new StringBuilder(); jsSerializer.Serialize(stu, sb); return sb.ToString(); } else return null; }
Client:
//javascript 字符串转json对象: var obj = JSON.parse(str); //javascript json 对象转字符串: JSON.stringify(obj);
Regarding the relationship between AjaxPro.2.dll and ajax.dll, it is said on the Internet that they are different. In fact, it is basically done by one person. I guess. Please download ajaxpro from the above website. This is the perfect version
After referencing the dll file, you need to configure the webconfig httphandler. The function is to transfer the above ashx request to our ajaxpro code, and then allow our client js to directly call the server method successfully.
<system.webServer> <directoryBrowse enabled="true"/> <handlers> <add verb="*" path="*.ashx" name="myhandler" type="AjaxPro.AjaxHandlerFactory,AjaxPro."/> <!--<add verb="POST,GET" path="ajax/*.ashx" name="myhandler" type="Ajax.PageHandlerFactory, Ajax" />--> </handlers> </system.webServer>
Then I won’t say much else. I’ll look directly at the server code later.
You can understand easyui as a bunch of extended controls. Just like jquery, you package the js objects and native html controls with his stuff, and then you can click on some of the methods written for you to help you process data conveniently. And it also has a default control appearance that is okay, which is really good for enterprise management software. For other software, you can only haha. Download the easyui file and put it into the project and introduce easyui related js and style files and jquery:
<script type="text/javascript" src="../jquery-easyui-../jquery.min.js"> </script> <link rel="stylesheet" type="text/css" href="../jquery-easyui-../themes/default/easyui.css" /> <link rel="stylesheet" type="text/css" href="../jquery-easyui-../themes/icon.css" /> <script type="text/javascript" src="../jquery-easyui-../jquery.easyui.min.js"></script>
Then, you can use easyui to render the native html control into an easyui control through css style or js code as introduced on the easyui homepage http://jeasyui.com/
<div class="easyui-dialog" style="width:px;height:px" data-options=" title:'My Dialog', iconCls:'icon-ok', onOpen:function(){}"> dialog content. </div> <input id="cc" style="width:px" /> $('#cc').combobox({ url: ..., required: true, valueField: 'id', textField: 'text' });
Yes, very convenient. In fact, there are quite a few good JS writers in China. They have created some UIs like this and that. You can choose between them, so let’s stick with this one. The most commonly used requirement is ajax server-side paging. Let’s get it done.
Let’s talk about this easyui datagrid first. To make it worse, put a table tag in the client html:
function bindDataToTb() { var keywordStr = $('#keyword').val(); $('#studb').datagrid( { queryParams: { keyword: keywordStr }, //url:"WebForm.aspx/BindData", toolbar: '#searchBar', pagination: true, pageNumber: , singleSelect: true, pageSize: , pageList: [, , ], loader: function (param, success, error) { var da = WebApplication.NewFolder.HelloAjaxNet.BindData(param.keyword, param.page, param.rows) if (da.value.rows == null) { success(); } else success(da.value); }, pagePosition: 'bottom', columns: [[ { field: 'stuNo', title: 'Id', width: }, { field: 'name', title: '名字', width: }, { field: 'age', title: '年龄', width: }, { field: 'loginName', title: '登录名', width: }, { field: 'loginPwd', title: '密码', width: }, { field: 'GradId', title: '班级Id', width: }, { field: 'gradName', title: '班级', width: }, { field: 'none', title: '操作', width: , formatter: function (value, row, index) { var btn = '<a class="editcls" href="#" onclick="delstuClick(' + row.stuNo + ')">删除</a>'; return btn; } } ]] }); }
具体看loader 和columns ,loader用于定义你以什么形式载入数据 定义了loader上面的url就没有必要了。
我这里的WebApplication1.NewFolder2.HelloAjaxNet.BindData(param.keyword, param.page, param.rows) 自然也是服务端的方法 用于检索数据的 。
关于这三个param.keyword, param.page, param.rows 是我们用于实现loader时 easyui那种设计方式故意暴露给我们的参数 方便我们使用。
param.keyword 是我们上面定义的 我们点搜索的时候需要往服务端传一个查询关键词 queryParams: { keyword: keywordStr }
param.page 是easyui自己的参数表示当前第几页 param.rows表示每页行数,每当你 点表格的 上一页 下一页 的时候 就会自动往loader 发翻页的参数 这个是自动的。
然后就从服务端获取数据填充表格 ,就是这么一个工作过程。 还有colums 我就不说了就是定义显示哪些列 和自定义列 那个很容易看懂。
easyui控件有属性 方法,调用方法 的形式总算像这样 :$('#studb').datagrid('reload') 这就相当于调用了#studb这个表格控件的reload方法了 然后数据就会自动刷新,每个控件的具体见文档。
服务端数据处理我们还是用entityframework 我一般都用codefirst的方式 这东西跟他自己的mssql数据库 结合的很好 用起很方便。
服务端代码:
//查询(带分页 [AjaxPro.AjaxMethod] public static WebApplication.DataEntity BindData(string keyword, int page, int rows) { //, ref int pageIndex, out int totalPage if (keyword == null) keyword = ""; int pageIndex = ; int pageSize = ; int totalPage; if (page != ) pageIndex = page; if (rows != ) pageSize = rows; MyDb db = new MyDb(); var data = from studentInfo in db.Students where studentInfo.name.Contains(keyword) select new { stuNo = studentInfo.stuNo, name = studentInfo.name, age = studentInfo.age, gradName = studentInfo.grad.gradName }; //var data = from studentInfo in db.Students where studentInfo.name.Contains(keyword) select studentInfo; totalPage = data.Count() % pageSize == ? data.Count() / pageSize : data.Count() / pageSize + ; if (pageIndex > totalPage) pageIndex = totalPage; else if (pageIndex < ) pageIndex = ; //var dt = DataList<object>.Create(data.OrderBy(r => r.stuNo), new StudentsInfo(), pageIndex, pageSize).Value; object dt=null ; if(data.Count()>) dt= DataList<object>.Create(data.OrderBy(r => r.stuNo), new { stuNo = , name = "", age = , gradName = "" }, pageIndex, pageSize).Value; WebApplication.DataEntity result = new WebApplication.DataEntity(); result.total = data.Count(); result.rows = dt; return result; }
关于数据部分 和EF linq 分页那些我就不贴出来了 完整示例下载里面有。走走看吧 试试看吧 完全无刷新 服务端分页,感觉棒棒哒
搜索那个我也不想说了哈 就是重新载入下数据而已,删除是通过自定义 列的方式 传id到js函数 然后调用服务端删除。然后要说下 录入功能 以及easyui自带 的表单验证也是相当方便的。
新建一个div 作为弹出层 里面有一个录入信息的表格 各种html控件 只要写上easyui对应的样式 就自动渲染了 看弹出层的 class="easyui-dialog" data-options="closed:true,title:'新学生注册',modal:true"
其实很简单噻看字面意思就明白了 这些参数 都在easyui的文档里有。验证 也是在html元素上写data-options 就可以了, :
<div id="addBox" class="easyui-dialog" data-options="closed:true,title:'新学生注册',modal:true" style="width: px; height: px"> <table class="auto-style"> <tr> <td>学生姓名:</td> <td> <input id="stuname" class=" easyui-textbox" data-options="required:true,missingMessage:'必填项!',validType:'email',invalidMessage:'email格式不正确!'" type="text" /></td> </tr> <tr> <td>班级: </td> <td> <input class="easyui-combobox" id="grad" name="grad" data-options="valueField:'id',textField:'gradName',required:true,missingMessage:'必填项!'" /></td> </tr> <tr> <td> <input id="saveBtn" onclick="saveClick()" type="button" value="保存" /></td> <td> <input id="Button" type="button" onclick="$('#addBox').dialog('close');" value="关闭" /></td> </tr> </table> </div>
新建按钮:
注意千万别用button 元素 就是这种 这是个坑 ,折腾了好久。
保存按钮调用 的js函数:
//保存信息 function saveClick() { var isvaliok = $("#addBox").form('validate');//包起来的需要提交信息的那个div框的id if (isvaliok == false) { $.messager.show({ title: '提示', msg: '请完善不正确的项后再提交', showType: 'show' }); return; } var stu = {}; stu.name = $("#stuname").val(); stu.age = ; stu.GradId = $("#grad").combobox('getValue'); stu.gradName = $("#grad").combobox('getValue'); if (isNaN(stu.GradId)) stu.GradId = null; var rst = WebApplication.NewFolder.HelloAjaxNet.addStu(stu); if (rst.value == "ok") { $('#addBox').dialog('close'); $('#studb').datagrid('reload'); var gradData = WebApplication.NewFolder.HelloAjaxNet.getGrad().value; $('#grad').combobox({ data: gradData }).combobox('reload'); } else { $.messager.show({ title: '提示', msg: rst.error.Message + rst.value, showType: 'show' }); } }
注意到了噻:
var isvaliok = $("#addBox").form('validate');//包起来的需要提交信息的那个div框的id if (isvaliok == false) { $.messager.show({ title: '提示', msg: '请完善不正确的项后再提交', showType: 'show' }); return; }
在easyui里进行验证很简单噻 只要在html代码里把验证格式定义好了 ,只需要传入一个最外面容器控件的id $("#addBox").form('validate') 就自动帮我们验证了。并且界面上还有提示 焦点自动放到第一个验证不通过的控件上去了 完全不需要我们动手。
当然我们在客户端 document.ready()的时候 必须要绑定表格和下拉框的数据:
$(function () { //页面初始化 //载入表格数据 bindDataToTb(); //载入班级下拉框 var gradData = WebApplication.NewFolder.HelloAjaxNet.getGrad().value; $('#grad').combobox({ data: gradData }).combobox('reload'); var fd = new FormData(); });
服务端保存的代码:
//添加 [AjaxPro.AjaxMethod] public string addStu(StudentsInfo stu) { MyDb db = new MyDb(); if(stu.GradId==null) { if (string.IsNullOrEmpty(stu.gradName) == false) { Grad grd = new Grad(); grd.gradName = stu.gradName; Grad grdOld = db.grads.FirstOrDefault(r => r.gradName == stu.gradName); if(grdOld!=null) { return "类别已存在"; } else { db.grads.Add(grd); stu.grad = grd; } } } db.Students.Add(stu); db.SaveChanges(); return "ok"; }
服务端代码 如果我们没有这个id的类别我们就认为这个类别是新的 ,新加一个类别 然后立即绑定 perfect 完美 ,棒棒哒
看上去是不是有模有样。做管理类软件还行。
这样ui 那样ui当你需要自定义样式的时候发现什么ui都是浮云,例如我说的国内的写js比较牛的 就已经造出来很多ui了 ,表格是很漂亮 很强大。 其实很多功能你还是用不到 你想改还很困难 当然我的js也是很菜的。 当你用到另一套ui 的时候又要熟悉它那一套 。我只想用个简简单单的自定义分页表格而已 或者像asp.net里的服务器控件repeat 流式布局 四个数据一行那种 你怎么做。 还是自己动手吧。php里面有前端模板。
我这里只是简单从实际需求了解下angular的威力 php里面模板什么的都是浮云 新建一个webform HelloAjaxNetAngular.aspx
注意这个例子 服务端代码我一律用上面的丝毫都不会变 只是前端变了,angularjs 的主打思想是mvvm 模式 就是wpf里面那种依赖属性 动态绑定 ,不知道你们用过没 反正我用过 感觉就一个字 爽 ,做这种数据库平台程序 mfc winform 都是渣。
angularjs 的基础我就不介绍了 哈 直接从需求入手 做一个分页表格 加 信息更新 功能
angularjs的网站是 http://www.angularjs.org/ 这个网址在国内也是访问不了的。一些相关的其他人的学习笔记有 http://www.angularjs.cn/ http://www.zouyesheng.com/angular.html
反正这两个教程看了下对我没 对我没起到啥作用 感觉跟嚼木渣样的 ,angularjs的理念虽然是mvvm 但是angularjs本身还是感觉晦涩难懂。
我就在这样一个半懂不懂的状态下写了这个例子 ,所有的操作 几乎都完全不需要向jquery那样动dom 。真心感觉到了他的强大。前端就一个controller函数 管整个页面,怎么一个一个的分 我也不明白 只知道controller 跟html限定一样的树状结构。没在范围的html元素不能访问其controller里的 变量。
我们来看这个controller 函数 ,我写的时候也没什么感觉 。就是感觉很存粹 就只感觉到两个东西存在 。业务逻辑在操作数据。 就像在写c#数据操作代码样:
function myCtr($scope) { var mod = [{ name: 'xiang', age: }, { name: 'xiang', age: }, { name: 'xiang', age: }]; $scope.data = mod; $scope.curobj = {}; $scope.pageEntity = { total: , rows: , page: , pgmsg: '' } //初始化默认第一页 $scope.initPage = function () { var firstPage = WebApplication.NewFolder.HelloAjaxNetAngular.BindData($("#txtkeyword").val(), $scope.pageEntity.page, $scope.pageEntity.rows); $scope.data = firstPage.value.rows; var pageEntityMod = {}; pageEntityMod.total = firstPage.value.total; pageEntityMod.rows = $scope.pageEntity.rows; pageEntityMod.page = $scope.pageEntity.page; var totalpage = pageEntityMod.total % pageEntityMod.rows == ? parseInt(pageEntityMod.total / pageEntityMod.rows) : parseInt(pageEntityMod.total / pageEntityMod.rows) + ; pageEntityMod.pgmsg = "共 " + pageEntityMod.total + "条记录 每页 " + pageEntityMod.rows + "条,共 " + totalpage + "页 ,当前第 " + pageEntityMod.page + "页"; $scope.pageEntity = pageEntityMod; $scope.curobj = {}; } //更新当前 选定的 $scope.modifyCur = function () { var rst = WebApplication.NewFolder.HelloAjaxNetAngular.updateStu($scope.curobj) //刷新表格 当前选中信息 复原 $scope.initPage(); alert(rst.value); } //下翻页 $scope.nextPage = function () { var totalpage = $scope.pageEntity.total % $scope.pageEntity.rows == ? parseInt($scope.pageEntity.total / $scope.pageEntity.rows) : parseInt($scope.pageEntity.total / $scope.pageEntity.rows) + ; var pagenewnum = $scope.pageEntity.page + ; if (pagenewnum <= totalpage) $scope.pageEntity.page += ; $scope.initPage(); } //上翻页 $scope.previousPage = function () { var pagenewnum = $scope.pageEntity.page - ; if (pagenewnum >= ) $scope.pageEntity.page -= ; $scope.initPage(); } //搜索 $scope.search = function () { } //选中一行 $scope.del = function (sender, curobj) { //所有行的颜色还原//设置选中那一行的颜色 var rows = $(sender.target).parent().parent().parent().find("tbody").find("tr"); for (var i = ; i < rows.length; i++) { $(rows[i]).css("background", "white"); } $(sender.target).parent().css("background", "#ffed"); $scope.curobj = curobj; } //首次先调用下 以获取第一页 $scope.initPage(); }
界面部分:
<div ng-controller="myCtr" id="mygrid"> <input id="txtkeyword" type="text" /><input ng-click="initPage()" type="button" value="搜索" /> <br /> <br /> <div style="height: px"> <table cellspacing="" border="" class="gridtable"> <thead> <th width="px">name</th> <th width="px">age</th> </thead> <tbody ng-repeat="stu in data"> <tr ng-click='del($event,stu)' style="background-color: white"> <td>{{stu.name}}</td> <td>{{stu.age}}</td> </tr> </tbody> </table> </div> <div id="pager"> <a href="#" ng-click="previousPage()">上一页</a> <a href="#" ng-click="nextPage()">下一页</a> <span>{{pageEntity.pgmsg}}</span> </div> <div> 姓名:<input type="text" value="{{curobj.name}}" ng-model="curobj.name" /><br /> 年龄:<input type="text" value="{{curobj.age}}" ng-model="curobj.age" /> <input id="Button" type="button" ng-click="modifyCur()" value="更改" /> </div> </div>
I saw that I made a data binding function by myself. Refer to the loader of datagrid in easyui. After the first request to get the paging information, I immediately bound the data to the table. You can see that it is exactly like making a template, and then initializes my own paging control. When ng-click is used, the client click is triggered as before, and then the method in the controller is called to update the data. Note that the data is only updated according to the business logic, and there is no need to do anything else. If you don’t understand the above two pieces of code, you can check it out by yourself. Getting started with angularjs and data binding takes less than 10 minutes,
Due to the two-way binding mechanism like WPF, when the data model data is updated, the page content will automatically change accordingly. You can even see that when I edit the data in the text box below, the data in the above table changes before it is submitted. Because their data comes from the same place, it feels like it is ajax.
The project source code of all the examples above can be downloaded and run directly, but due to the introduction of some external libraries, it is almost too big to fit in 10MB
Something to say
In fact, if the Internet continues to develop like this, the front end will be unified, and the front end will be king. By then, a web page will be a system and a client. The backend is only responsible for data and security. Isn’t HTML5 now almost an industry standard? Some embedded devices support it
For the time being, I have seen a few people in the blog garden talking about the MVC mode where the front end and the back end operate on the same model. When the front end updates attributes, there is a mechanism that automatically updates the back end for persistence. Go to the database or update a certain attribute of the model in the backend, and the value of the front-end html page will automatically change. It’s not that it can’t be done. After all, there are so many talented people, so I think it’s at least not stable yet.
Various UIs include easyui ligerui fineui miniui Devexpress and many js frameworks seajs requirejs JavaScriptMVC backbone avalonjs knockout angular jquery jqueryui js is really shit, I can’t finish learning all kinds of frameworks
Especially the software industry is changing with each passing day. There are too many technologies based on frameworks and platforms. If you are not proficient in a certain technology, it doesn’t matter if you can use it. But as a technician, you must be proficient in at least one or one technology. Otherwise, it is a pity that you are just a fool. I'm basically still on the road to moving bricks. Writing business code means using one year's experience for ten years. Writing business code is his job. After work, he has to have some energy to investigate the essence of things. As long as a good programmer has been working on this kind of database system for a long time, he will know how to do it himself. Develop some so-called small frameworks that can be developed quickly to accumulate some of your own tool libraries and experience.
Don’t have any bias at work. As long as he can write business code every day, software development is just a profession. You are not a hero. The purpose is to solve problems, not to turn the corner.
I personally am not very fond of js. js is also terrible. When this thing was originally designed, it was not perfect and caused various obstacles to our use of it. However, you have to use it when doing web development. There is no prejudice against those who do front-end work here. Thanks to those who have a thorough knowledge of the front-end, such as Situ Zhengmei, for creating these tools to make it easier for us to complete these website programs.