一、前三篇的内容是否对您有帮助呢?如果有的话,请您继续关注这篇吧,这篇主要是实现”用户管理“的功能,多种方式的增删改查,以 及对用户权限的分配,查询的时候,下面左截图中,用户姓名的模糊查询,输入w,包含w的用户名显示在下拉框中,如果数据太多,也可以使用Jquery-EasyUI的CommboGrid,请看下面的右截图。
(1)用户管理的“增删改查”,一个最基本的功能了,但是在Jquery-EasyUI中有多种方式进行增删改查。如下图:
(2)、在这个用户管理里,也可以对应的实现一个用户的权限分配功能,使用ZTree树结构的方式清晰的分配,当然使用Jquery-EasyUI的Tree也可以。
二、废话少说,赶快实现前面展示的这些功能吧!
1、首先是展示数据的部分,使用的是Jquery-EasyUI的Datagrid,其中是带分页的,属性设置(pagination: true,),返回的数据是Json类型(total:总条数,rows:详细数据,一个集合类型)。
2、MVC中ActionResult的小弟里有个JsonResult,正好返回Json类型,不需要Json序列化。
3、由于带分页,前台肯定得传值,Request["page"](当前页),Request["rows"](分页大小),我这个使用的传统的方式,由于这个是MVC项目,也可以 利用MVC中的ModelBinder。或者使用这种方式public ActionResult UserManeger(int page,int rows),使用火狐浏览器的Firebug,调试看看传过去的参数。
4、Jquery-EasyUI中有两种方式进行渲染,一个是在标签中直接写,还有一种方式是Jquery的形式,这个功能中用的是Jquery的方式,每一块代码部分都有解释和说说明,包括(右键行出现Menu、增删改查的功能,Jquery-EasyUI的每个属性如果不熟悉的话,建议看看官网的例子。如果挨个解释的话,内容确实太多了。)
public ViewResult UserManeger()
{
return View();
}
[HttpPost]
public ActionResult UserManeger(string name,string SubAction)
{
int pageSize = 5;
int pageIndex = 1;
int.TryParse(this.Request["page"], out pageIndex);
int.TryParse(this.Request["rows"], out pageSize);
pageSize = pageSize <= 0 ? 5 : pageSize;
pageIndex = pageIndex < 1 ? 1 : pageIndex;
var UserList = userBll.GetAll();
var temp = UserList
.OrderBy(u => u.UserName)
.WhereIf(u => u.UserName.Contains(name), name != null)
.Skip<User>((pageIndex - 1) * pageSize)
.Take<User>(pageSize)
.ToList();
Hashtable ht = new Hashtable();
ht["total"] = UserList.Count();
ht["rows"] = temp;
return Json(ht, JsonRequestBehavior.AllowGet);
}
ViewBag.Title = "用户管理";
Layout = "~/Areas/houtai/Views/Shared/_JS.cshtml";
}
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>用户管理</title>
</head>
<body>
<script type="text/javascript">
$.canEdit = true;
</script>
<script type="text/javascript">
$.canDelete = true;
</script>
<script type="text/javascript">
$.canGrant = true;
</script>
<script type="text/javascript">
function editFun() {
alert("编辑");
}
</script>
<script type="text/javascript">
// var editFlag = undefined;
$(function () {
initable();
bindRegistButtonClickEvent();
upDateUserDll();
$('#cc').combobox({
mode: 'remote',
url: "@Url.Action("UserList","Privilige")",
valueField: 'UserName',
关于这个话题,其实在(六)里面已经讨论了一半了。学过Haskell的都知道,这个世界上很多东西都可以用monad和comonad来把一些复杂的代码给抽象成简单的、一看就懂的形式。他们的区别,就像用js做一个复杂的带着几层循环的动画,直接写出来和用jquery的"回调"写出来的代码一样。前者能看不能用,后者能用不能看。那有没有什么又能用又能看的呢?我目前只能在Haskell、C#和F#里面看到。至于说为什么,当然是因为他们都支持了monad和comonad。只不过C#作为一门不把"用库来改造语言"作为重要特征的语言,并没打算让你们能跟haskell和F#一样,把东西抽象成monad,然后轻松的写出来。C#只内置了yield return和async await这样的东西。
把"用库来改造语言"作为重要特征的语言其实也不多,大家熟悉的也就只有lisp和C++,不熟悉的有F#。F#除了computation expression以外,还有一个type provider的功能。就是你可以在你的当前的程序里面,写一小段代码,通知编译器在编译你的代码的时候执行以下(有点类似鸡生蛋的问题但其实不是)。这段代码可以生成新的代码(而不是跟lisp一样修改已有的代码),然后给你剩下的那部分程序使用。例子我就不举了,有兴趣的大家看这里:http://msdn.microsoft.com/en-us/library/vstudio/hh361034.aspx。里面有一个例子讲的是如何在F#里面创造一个强类型的正则表达式库,而且并不像boost的spirit或者xpress那样,正则表达式仍然使用字符串来写的。这个正则表达式在编译的时候就可以知道你有没有弄错东西了,不需要等到运行才知道。
Haskell和F#分别尝试了monad/comonad和computation expression,为的就是能用一种不会失控(lisp的macro就属于会失控的那种)方法来让用户自己表达属于自己的可以天然被continuation passing style变换处理的东西。在介绍C#的async await的强大能力之前,先来讲一下Haskell和F#的做法。为什么按照这个程序呢,因为Haskell的monad表达能力最低,其次是F#,最后是C#的那个。当然C#并不打算让你自己写一个支持CPS变换的类型。作为补充,我将在这篇文章的最后,讲一下我最近正在设计的一门语言,是如何把C#的yield return和async await都变成库,而不是编译器的功能的。
下面我将抛弃所有跟学术有关的内容,只会留下跟实际开发有关系的东西。
一、Haskell和Monad
Haskell面临的问题其实比较简单,第一是因为Haskell的程序都不能有隐式状态,第二是因为Haskell没有语句只有表达式。这意味着你所有的控制流都必须用递归或者CPS来做。从这个角度上来讲,Monad也算是CPS的一种应用了。于是我为了给大家解释一下Monad是怎么运作的,决定来炒炒冷饭,说error code的故事。这个故事已经在(七)里面讲了,但是今天用的是Haskell,别有一番异域风情。
大家用C/C++的时候都觉得处理起error code是个很烦人的事情吧。我也不知道为什么那些人放着exception不用,对error code那么喜欢,直到有一天,我听到有一个傻逼在微博上讲:"error code的意思就是我可以不理他"。我终于明白了,这个人是一个真正的傻逼。不过Haskell还是很体恤这些人的,就跟耶稣一样,凡是信他就可以的永生,傻逼也可以。可惜的是,傻逼是学不会Monad的,所以耶稣只是个传说。
由于Haskell没有"引用参数",所以所有的结果都必须出现在返回值里面。因此,倘若要在Haskell里面做error code,就得返回一个data。data就跟C语言的union一样,区别是data是强类型的,而C的union一不小心就会傻逼了:
然后给一些必要的实现,首先是Functor:
fmap f (Sure x) = Sure (f x)
fmap f (Error e) = Error e
剩下的就是Monad了:
return = Sure
fail = Error
(Sure s) >>= f = f s
(Error e) >>= f = Error e
看起来也不多,加起来才八行,就完成了error code的声明了。当然就这么看是看不出Monad的强大威力的,所以我们还需要一个代码。譬如说,给一个数组包含了分数,然后把所有的分数都转换成"牛逼"、"一般"和"傻逼",重新构造成一个数组。一个真正的Haskell程序员,会把这个程序分解成两半,第一半当然是一个把分数转成数字的东西:
Tag f =
if f < 0 then Error "分数必须在0-100之间" else
if f<60 then Sure "傻逼" else
if f<90 then Sure "一般" else
if f<=100 then Sure "牛逼" else
Error "分数必须在0-100之间"
后面就是一个循环了:
TagAll [] = []
TagAll (x:xs) = do
first <- Tag x
remains <- TagAll xs
return first:remains
TagAll是一个循环,把输入的东西每一个都用Tag过一遍。如果有一次Tag返回失败了,整个TagAll函数都会失败,然后返回错误。如果全部成功了,那么TagAll函数会返回整个处理后的数组。
当然一个循环写成了非尾递归不是一个真正的Haskell程序员会做的事情,真正的Haskell程序员会把事情做成这样(把>>=展开之后你们可能会觉得这个函数不是尾递归,但是因为Haskell是call by need的,所以实际上会成为一个尾递归的函数):
TagAll xs = reverse $ TagAll_ xs [] where
TagAll [] ys = Sure ys
TagAll (x:xs) ys = do
y <- Tag x
TagAll xs (y:ys)
为什么代码里面一句"检查Tag函数的返回值"的代码都没有呢?这就是Haskell的Monad的表达能力的威力所在了。Monad的使用由do关键字开始,然后这个表达式可以被这么定义:
::= "do" FragmentNotNull
FragmentNotNull
::= [Pattern "<-"] Expression EOL FragmentNull阅读更多内容
没有评论:
发表评论