由var js = confirm("确认操作?");引发的技术难题
看到本文的标题,或许有的朋友问感到疑惑,confirm会引起技术难题吗?是小问题吧,是小问题?这里我要说的不是小问题,而是一个使用confirm引起的技术难题.或许有的朋友会疑惑了,confirm不就是弹出一个确认对话框吗?用户只有两种选择,要么点"是",要么选择"否",也许会有人会专牛角尖的说:"用户出了点"是"和"否"外,还有点"X".是的,没有错,confirm能够操作的就这三种,而点"X"执行关闭和点"否"是同理的.OK,回到主题,既然confirm是用来确认用户的某项目操作的,那它会引起什么样的技术难题呢?
在继续探讨这个技术难题之前,首先感谢园里的两位好热心的同志,一个是包包,另一个是大V.就上面这个问题,我和包包讨论了很多,然后是大V,那怕是深夜了,我向他提起这个问题,他仍然不休息的和我讨论.经过和两位大师的讨论,各自都有不同的看法和思路,可最后还是没有找到完美的解决方案.^.^凌晨一点我休息的时候,大V还说:"我去做个实验研究下.",呵呵,希望大V可以研究出一个好的解决方案,然后指导我完成项目中的这个难题,在此先谢了.这个问题或许在不久之前已经有不少朋友遇到过,或许正在看本文的你在不久之后也会遇到.
问题在什么地方
做个WinForm的朋友可以说是没有谁不知道MessageBox.Show()这个方法吧。不错,在win程序里就是使用他来做用户确认操作,如下图:
是的,上面正是我们使用得非常熟练的MessageBox提示,那么我们在WEB开发中能这样来做提示,然后根据用户的选择执行相应的业务操作吗?说到WEB上,或许大家马上就想到了使用"window.confirm()"来做操作提示,不错,先看看下图:
如上图示,发现问题了吗?很简单的一个应用示例.比如在做业务系统的卡片里,当前卡片读取了一条数据显示在卡片上,此时用户已经对可片是的部分数据进行了修改,接下来当你不点保存而就直接去点新建操作的时候,就应该提示用户"当前数据已经修改,是否保存?",根据用户的选择执行相应的操作(是:保存当前数据,将界面控件元素的值清空,这个插入新的数据;否:不保存当前数据直接进入新增状态.).
在看上图的代码,举例说我们需要开发一张业务单据(如:采购单/销售单),在某种情况下要通过用户确认才能做随后的操作,入上的JS代码(string js="window.confirm('........')"),result用来存储确认对话框的返回值,根据用户选择确定执行某项操作,这个需求在Winfrom里是非常简单就能够实现的,confirm是纯客户端的方法.那么在WEB开发中又怎么来实现这个功能呢??
答案是不能实现.经过多种多次的实验都是以失败告知.因为在服务端的C#代码里得不到客户端的JavaScript方法的返回值.
猜想解决不了问题
这里其实我们可以尝试来做一个不成功(因为我实验过)是实验,在实验之前我有这样一个猜想,服务端的C#代码里我们通过ScriptManager.RegisterClientScriptBlock();方法来执行客户端的JavaScript方法,在这个客户端方法里我们通过去调用ASP.NET AJAX所支持的PageMethos方法,页面.cs里定义一个static变量,当服务端的RegisterClientScriptBlock执行的时候会调用指定的客户端方法,该方法则回调页面.cs里的PageMethos这样来实现将确认操作回传;
2{
3 private static string key = string.Empty;
4 protected void Page_Load(object sender, EventArgs e)
5 {
6 if (!IsPostBack)
7 {
8
9 }
10 }
11
12 protected void Button1_Click(object sender, EventArgs e)
13 {
14 ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "js", "test()", true);
15 if (key == "true")
16 { }
17 else
18 { }
19 }
20
21 [WebMethod]
22 public static void GetOperationResult(string result)
23 {
24 key = result;
25 }
26}
2</asp:ScriptManager>
3<script type="text/javascript">
4function test()
5{
6 var js = "confirm('确定吗?')";
7 PageMethos.GetOperationResult(js.toString());
8}
9</script>
这样做能解决问题吗?不能.虽然是在按扭的事件里执行的客户端方法,而可户端方法又回调服务端的PageMethos方法,这样貌似可以回传数据.没错,是可以回传数据,但是这还是不能满足我们的需求.在实验过程中通过调试发现,只有当按扭的实现方法(Button1_Click())退出后才会弹出确认对话框.........,实验证明,猜想就是猜想,仍然解决不了问题.
怪异想法引发新问题
突然我想到了一个很怪异的办法,带着尝试与猜想去实验了一下,OK成功了.怎么做的呢? 既然Winform里的MessageBox可以用来做提示,WEB中是不是也可以使用他呢?MessageBox封装在System.Window.Forms下,通过实验将System.Window.Forms.dll引入到WEB项目,然后通过MessageBox在ASP.NET里来做确认提示.这样的想法是对是,实验也成功了,那么现在是不是就已经水道渠成了呢?未必,当使用System.Window.Forms的MessageBox来做确认提示来解决了ASP.NET里的确认提示的问题的同时,新的问题出现了,System.Window.Forms的MessageBox在ASP.NET下不能实现"模态",现在好象又回到了没有引入System.Window.Forms的MessageBox来解决确认提示的问题之初.本文的第一张图其他就是在ASP.NET里使用MessageBox的效果,如下:
简单问题复杂化吗?
也许正在看本文的你或许会说我是不是脑袋有问题,把一个简单的问题弄得这么的复杂.那好,试问你有没有仔细想过这个功能的重要性呢?个人认为这个功能是很重要的,特别是在系统里有复杂的业务关系,一个错误的操作有可能引发XXX的情况下.提示用户是很必要的,也是非常重要的.
既然在Winfrom下可以很简单的就实现这个功能,WEB上实现却是这么的复杂,这也许是WEB本身是基于请求与响应的模式的原因.^.^不过希望那一位控件高手能够开发出这样的控件,期待ing.......
我再一次怪想
window.confirm()只能在可户端里执行,而且可以很方便的得到返回值,程序员们也可以很方便的使用这个返回值进行相应的业务处理.JavaScript不是也OO吗?在某种程度上说是方便了很多,前段时间还闹得很凶的.基于上面的种种原因,试想我们可以把业务拿到客户断来做吗?客户端来处理,公共的方法通过JS封装,加上ASP.NET AJAX所提供的强大功能,可以和服务端时时通信.我们是不是可以换种开发模式,将平时的页面cs的业务处理放到客户断用JavaScript来处理呢?
呵呵,这种方式其实是可行的.虽然可行,却存在所许多的问题,比如对团队开发人员的技术(客户端JavaScript,AJAX等)要求更高,降低开发效率影响开发进度,页面逻辑代码不能够完美的封装等.
该何去何从
一位老师常对我说的一句话是:"你不要给我说你想怎么做,打算怎么做,你就直接告诉我你能不能做.",就本文所讨论的这个问题能做吗?我是不能做的,这点或许从CS转向BS开发的朋友最清楚. 这不是我们做技术人的问题,而是WEB自身的缺陷.问题是不能老挂着不理的,始终都需要给出一个解决方案,就这个问题而言,我们是放弃这个确认提示功能吗? 对于我来说,我只有放弃了.
本文就此结束,我尊敬的朋友,或许即将关闭本页的你曾经遇到过同样的问题,你是怎么处理的呢?有什么好的方案吗?还望能够指导后生学习,先谢了.