子非鱼,安知鱼之乐?
RSS地址:
http://www.unfish.net/feeds/index.rss2共有25篇文章被收藏推荐
收录于2007-06-13
认领
报错
推荐
32
最新文章
精华文章
32位订阅者
在Asp.net中做一个用户控件ascx页面,其中定义一个Public的属性,比如PageID,在aspx页面中放入这个用户控件,给它分配一个ID,比如MyControl,然后在cs页面中给这个用户控件的这个属性赋值,MyControl.PageID=1;这是非常通用的而且常见的作法。
但是假如这个时候给这个用户控件加一个输出缓存
<%@...
在Asp.net中做一个用户控件ascx页面,其中定义一个Public的属性,比如PageID,在aspx页面中放入这个用户控件,给它分配一个ID,比如MyControl,然后在cs页面中给这个用户控件的这个属性赋值,MyControl.PageID=1;这是非常通用的而且常见的作法。
但是假如这个时候给这个用户控件加一个输出缓存
<%@ OutputCache Duration="600" VaryByParam="*"%>
这个aspx页面就会报错,当控件被缓存以后,页面里将得不到MyControl对象,该对象始终为Null。
解决方法:赋值前判断一下MyControl!=null就行了。因为控件的缓存本身会判断URL参数是否相同,所以不用考虑多个页面之间控件的参数值混淆的问题。
搜狗成功的以抄袭问题阻击了谷歌输入法以后,似乎有点喜欢上这一招了,如今QQ输入法更新速度有点快,然后,搜狗拼音的官方博客就出现了一篇指责QQ输入法抄袭自家输入法创新功能的文章,不过很快,此文章又被删掉了,但是还是留下了快照。...
搜狗成功的以抄袭问题阻击了谷歌输入法以后,似乎有点喜欢上这一招了,如今QQ输入法更新速度有点快,然后,搜狗拼音的官方博客就出现了一篇指责QQ输入法抄袭自家输入法创新功能的文章,不过很快,此文章又被删掉了,但是还是留下了快照。
软件功能的创新当然是个高难度的技术活,但是软件开发本身并不是一个很容易垄断的行业,不是说你做出了某个别人没有的功能,别人就再也不能做这个功能了,否则的话,也就没有技术壁垒这个说法了……很容易的被人模仿成功,只能说明这个功能还不够NB罢了。就像Facebook,整站的功能被人模仿又能怎么样呢?你能做SNS就不允许别人的网站出现交友功能了?
搜狗删掉文章是不是因为知道自己说错了话?腾讯喜欢模仿(或曰抄袭)那是一回事,自己小肚鸡肠就是另一回事了。
周末闲来无事,加上心情不错,决心突破一下Extjs给我留下的心理障碍,过了这道坎。重新下载了extjs 2.2的文件包,然后开始狂搜入门文章,真的是太少了。然后开始找几个看起来比较顺眼的demo,猛看源代码。
要上手当然要有个程序来下手,前两天简单做过的关于Getting Things...
周末闲来无事,加上心情不错,决心突破一下Extjs给我留下的心理障碍,过了这道坎。重新下载了extjs 2.2的文件包,然后开始狂搜入门文章,真的是太少了。然后开始找几个看起来比较顺眼的demo,猛看源代码。
要上手当然要有个程序来下手,前两天简单做过的关于Getting Things Done的那个工作任务管理程序真是再适合不过了,功能简单,貌似有用,界面少,却可以独立成站,而且已经有了成型的思路(甚至成型的程序),上手要容易很多,只要把精力关注于Extjs上面就可以了。
进入开发环境,用现成的项目复制出一套Django的运行环境,把用户注册登录和任务管理的部分复制过来,稍微改点配置,建立数据库,运行测试服务器,OK,可以跑起来了。
然后把extjs的js文件,css文件和图片文件复制过来,正式开工。
首先是确定页面布局,走了不少弯路。一开始new出四个Ext.Panel放到页面上,结果四个自动垂直排列下来,我想把它搞成横着四列的,结果各种布局的名字和解释研究来研究去找不着门,后来,先在body里放了个table,做四列一样宽的td,里面放个带id的div,然后指定每个Panel的renderTo属性到各自的div,嗯,虽然方法很丑陋,但是效果算是出来了。以后再优化吧。在Table前面加个div,再new一个Panel,做成Header。
然后是显示任务内容。js与服务器端的交互不用说了,肯定是json,不过django的序列化功能自动生成的json格式太奇怪,还是自己拼字符串来的方便。extjs有个JsonReader,从JsonReader又找到了JsonStore,这个东西本身就是JsonReader和HttpProxy的综合体,可以直接设定URL参数读取返回的JSON数据并解析成Data数据源。配合XTemplate,可以很方便而且自动的生成DataView。XTemplate就是普通的HTML,有几个简单的TPL标记可以用,比如JSON里面的每一条记录为{id:1,name:’jason’,title:’标题’},那么在TPL的定义里就可以直接在HTML中间插入{name},在生成DataView的时候就可以自动把对应的值替换进去,生成的DataView中的每一行都是一套完整的TPL模板。
嗯,看起来很简单,实际也确实如此,在四个Panel的items属性里分别new一个DataView,加上tpl和store的属性,就OK了,可以读取并显示出来了。HTML定义成什么样,显示出来的就是什么样。简单起见,每行放一个div,里面放一个table用来布局。
随后就遇到了第一个难题,JSON里面有两个字段是int型,但是显示的时候需要显示成对应的文本,比如重要性字段,0代表重要,1代表一般,2代表不重要。但是在XTemplate和JsonStore里面都没有找到合适的办法来简单的替换这个值,花了三个小时仍然没有找到可以使用JS数组来自动替换的方法,最后,又一次妥协了,在TPL里面用三个if语句来输出对应的文本。啊,好土。
显示问题已经解决,剩下就是往服务器上保存数据的问题了。按照以前的习惯,我会在服务器上建一个没有框架的页面,用于在Ajax里加载该页面显示在当前页的一个层里面,这样新建或者编辑数据的时候,都是在服务器端初始化各个字段的内容,相对于用JS来初始化HTML字段来说,要容易很多。但是Extjs既然号称富客户端,当然不能这么干了,嗯,就用JS来生成这个写数据的时候的对话框吧。
先是在网上找到了做登录窗口的代码,new一个Ext.FormPanel,定义标题、宽、高等,在它的items属性里放多个Field,Extjs已经定义了许多不同的Field类型,比如TextField,PasswordField,TextArea,ComboBox等等,而且,字段还有自带的客户端验证,可以很方便的验证是否为空(不允许为空的字段都填完之前提交按钮始终是禁用的),两次输入的密码是否一致,Email是否合法等等,非常方便。而且FormPanel里面的Form还可以通过一个URL获取一条记录的JSON格式数据,自动初始化各个字段的值,用于编辑记录的时候真是太方便了。而且配合Ext的QuickTips,错误提示也非常友好。
以这个抄来的登录窗口为原型,完成了登录注册和添加新任务的对话框,而且服务器端的代码也非常简单,因为现在不需要处理GET事件了,只要管POST的结果就可以了,登录过程还是跟以前一样,直接记在session里就可以(django会自动发送sessionid到客户端,保存在客户端cookie里)。四种不同类型的任务所需要的字段不同,但是大家用的是同一条记录,弹出的也是同一个编辑框,根据任务类型来判断需要显示哪些字段就可以了。
用了一天半的时间,将完整的任务管理程序移植成了一个新站点,并且完全的Extjs操作,很有成就感。给新站点起个名字SimpleLife,简单生活,让你的生活变得更简单。目前放在原有域名下,懒的买新域名了。有兴趣的朋友可以试试看:http://sl.unfish.net 本文秉承本人的不贴代码的习惯,不过JS开发网站的好处就是,你可以把网页另存为……
Extjs版的SimpleLife靠一段落,接下来要攻克的就是Adobe...
Extjs版的SimpleLife靠一段落,接下来要攻克的就是Adobe Air了。这个东西出来的时间已经很长了,前面看它的开发方式一直云里雾里,下手似乎有些困难,但是唯一的印象就是,通过AIR可以直接把HTML和JS写的网站包装成客户端程序来运行。既然如此,那用Extjs的富客户端方式写的网站岂不是可以直接移植成客户端程序?果然有如此好事?
于是,又是一番疯狂搜索,看了一些AIR的入门文章,写了一个HelloWorld的网页,根据网上的说明,建个目录,写个application.xml的起始文件,下载了AIR SDK,无需安装,解压后直接把bin目录配置到系统环境变量的Path里面去,在命令行窗口里进入网页所在目录,运行adl application.xml,哇,果然很帅啊。
接下来,把SimpleLife里面的index.html(整个网站就这么一个html文件),以及用到的Extjs相关的文件全部拷过来,把js里面读写数据涉及到的URL全部加上域名变成绝对路径,再启动,哇塞,真的可以启动起来啊!
但是用AIR做客户端的初衷就是可以让这东西方便的停留在桌面上,随时使用,当然不好像网页似的搞个全屏大的程序了,所以,最理想的布局就是像QQ面板那样折叠。在extjs的Demo里面,有左侧导航栏就是这个样子的,看起来应该也很容易。谁知道,真的想实现这个效果,还真是花了不少功夫。最终的结果是,new一个Ext.ViewPoint,这个东西是自动填充整个body区域并负责内部组件布局的。然后把它的layout属性设成border。border类型的布局就是经典的应用程序布局,把整个body分成东南西北中五大块,除了center,其它都是可选的。所以在ViewPoint的items里new一个Panel,将Panel的region属性设为center,这个Panel就自动充满整个窗口了,然后把这个Panel的layout属性设为accordion,然后把四个Panel放在它的items属性数组里。这样四个Panel就变成QQ面板那样的自动伸缩样式了。
嗯,看起来不错。但是随后就遇到了另一个极其困难的问题,DataView里面根据XTemplate生成的各个操作按钮,都是用的<a href="javascript:;" onclick="ShowEdit()">这样的代码,结果,现在在AIR里所有的onclick都失效了,怎么点都不管用。
随后查阅air的官方文档和开发手册,里面有提到air的安全模型的问题,主程序域里的html代码里是不允许使用onclick这种代码的,因为主程序域的权限极高,可以删除用户的硬盘文件。不过你可以在主页面里用一个iframe加载另一个页面,这个页面会运行在另一个域里面,而它就可以使用onclick或者eval这样的函数,但是,这个域的安全性却决定着它不能操作本地文件和URL,所以读写远程数据的事情它又做不了。
手册里面的解决方案是在主页面里定义一些函数,然后在子页面里可以使用它的父域这个属性来执行父页面里面定义的函数,这样就可以完成两者之间的通信了。但是,这也太麻烦了吧。麻烦还是其次的,当我把页面布局的代码放到iframe里面的页面里时,整个布局就被破坏了,宽高很难掌握。于是还是回到了原来的轨道上,只是得换个思路解决问题。
有趣的是,Panel的标题栏上的两个按钮功能却不受影响,仍然可用。那就是说,用Ext生成的按钮是没有问题的。但是,如何在XTemplate里面生成Ext按钮呢?又花了一个小时,最终证明XTemplate真的是很单薄,无法在里面插入JS函数,也无法把它的模板字符串跟JS函数串联起来。
换一个思路来解决问题,在DataView生成以后,再用Ext来替换其中的内容。尝试在DataView的render事件中处理,发现这个事件被调用的时机有点问题,最后测试在DataView里面的JsonStore的load事件里进行处理,倒是可以用了。但是一个更神奇的问题出现了。在load事件里根据DataView生成的代码里面a的id找到每一个a,给它添加click事件,调用一个匿名函数,在该函数里alert出这条记录的title。结果,所有的a点击弹出的都是第一条的title,怎么看这个循环都没有写错啊。
在这个地方又折腾了一个小时,extjs的demo很不详细,API文档虽然详细却又没有demo和参数的说明,无论如何找不到解决方案。最后,又是使用了一个折衷方案:让a的onclick的函数传递this.id作为参数,这下所有的a点击的时候都能正确的调用函数了。把原来调用显示编辑框的时候需要的三个参数用下划线串起来作为每个a的id,然后被调用的函数再拆分字符串,还原成三个参数去调用原来的函数,嗯,测试一下,没问题了。
按照原来页面的显示编辑窗口的方式,这个窗口仍然是以一个弹出层的形式显示在原来的浏览器窗口里,现在就是显示在AIR的窗口里,而AIR窗口现在是一细条,对话框还显示在这里面就有点不爽了。其实ext的air命令空间里是有个函数可以创建普通的弹出窗口的(就像普通的应用程序的新窗口一样,完全独立于主窗口的),但是在air里面,这个弹出的窗口还需要一个html,这个html还需要一套初始化窗口的js,而如何控制这个窗口的宽高就成了问题。因为这个窗口根据不同的任务类型,大小是不一样的。
通过这种调用方式,主窗口往弹出窗口里传递参数只能通过URL来传递,比如edit.html?id=1&type=2,然后在子窗口的js里取window.location再用字符串解析的方式把所有的参数拆出来。非常的麻烦,倒也是可行的。算了,下次改进的时候再说吧。
测试完成以后,根据参考手册上的说明,生成一个密钥文件,然后将整个目录打包成air文件,发现无法调用这个air文件。原来AIR的SDK只是用来开发,不带运行功能,汗……这一点跟java和.net都不一样。再下载air runtime(发现也需要15M,有点大),安装。然后双击自己生成的air文件,会提示是否要安装,安装界面上显示开发商是未知。想要把这个开发商变成自己的名字,需要像ssl一样购买versign的证书,全球一共就那三四个能卖这种证书的,贵的要1800,便宜的也需要1280一年,靠,当我的钱是天上掉下来的啊?看来我是无福消受了。
把生成的air文件发给朋友,安装测试,完全没有问题。嗯,折腾了一天,总算有点收获。只是不知道这玩意儿跟用.net写个windows客户端程序相比有什么优点?大概就是同一个air程序可以在mac,win,linux上安装并运行(因为js本身兼容性不错)。不过AIR开发的程序丝毫不为开发人员考虑问题,它有着js开发的的同样的缺点,你打包出来的air程序只是个普通的zip文件,而且安装完成后你所有的源代码都在它的安装目录下,丝毫没有加密,别人也完全可以再打包……不知道adobe当初这样设计的初衷是什么?是为了让新手可以得到更多的免费demo吗?
不过既然有了这类似SOA架构的网站核心,用什么方法开发前端软件就是小意思了,甚至可以做成Vista侧边栏组件,Yahoo widget组件,甚至猪八戒桌面程序的组件。但是目前的登录方式只采取了cookie的方式来记录用户,这要求该开发方式能够接收并保存cookie。想达到最大的兼容性,还需要换一种方式,就是登录的时候直接把用户的sessionid返回给客户端,然后客户端每次请求都发送这个sessionid作为辅助参数,这样就可以让任何开发语言都可以使用了。
如果你有兴趣试试这个,可以下载:http://sl.unfish.net/uploads/SimpleLife.air 注意大小写。


