从控件开发的角度看几个editor控件,Freetextbox,radtoolbar,abouteditor,cuteeditor
首先是FreeTextbox
此控件是生成的控件(相对于复合控件),不论是toolbar还是toolbaritem,都不是以子控件的形式存在,因此有更好的性能。这种方式的缺点是,不能很好的利用现有的Asp控件,降低了用户自定义控件的方便性。如,我想在toolbari上加上combox,必须自己实现。
视图状态,视图状态的管理是令人头疼的问题,弄不好就会加大视图状态的大小。从Freetextbox对视图状态的实现来看,它的实现中规中矩,完全符合ms推荐的实现方式。但是,是否每个toolbaritem都有必要实行视图状态?其实从Freetextbox的实现分析,大部分的实现是不必要的,因为他们都不会改变。如果把这些实现剔除,Freetextbox的代码会简单很多。
子控件的实现方式,此控件不存在子控件,toolbaritem被定义为实现了IstateMananger的类,每个Item都是一个类,如Bold,Italic等。
总之,这个控件的服务器段代码,十分符合MS推荐的控件实现方式,它的内部实现,类似于ASP的服务器控件实现。也符合常人的思路,代码比较容易理解。结构也不错可以给80分。
其次,Radtoolbar
此控件用的是复合控件。每个toolbaritem都被实现为子控件,并且暴露给客户。从用法来看比较像asp的一些复合控件,即子控件要在aspx中声明。但这种方式对客户来说,用起来很不方便,因为要写许多声明代码。
视图状态,此控件对视图状态的管理,可以说坏到了极点。它竟然通过把控件的属性序列化为xml,然后把xml作为视图状态。这就造成,任何一个细微的改变,都会把视图状态项记为dirty,造成整个xml序列被序列化的客户端。再者xml本身就包含许多不必要的文本,如<sdds>ss</sdds>。可以看到元素名称是很浪费空间的。这就造成此控件的视图状态,会比标准的asp实现大十倍左右。
子控件的实现方式,子控件是通过序列化的方式从配置文件读取。子控件没有细分,如没有类似于Bold,Italic的项。只被粗略分成了Toolbarbutton,toolbarseprator等。
总之,这个控件实现没有细看,因为不论从哪方面来说,它都算不上优秀。50分。
AboutEditor
这个控件的实现类似于Freetextbox,也不是复合控件。
视图状态,他没有为toolbarItem实现视图状态,因为这几乎没必要。
子控件,他同样不存在子控件,与freetextbox的不同在于,他没有细化每个toolbaritem。
总之,此控件和freetextbox很相似,我没有细看。
最后是Cuteeditor
看了他的demo,很震撼,应该是所有editor中效果最好的。
Cuteeditor用复合控件实现,缺点是增加了控件树的开销,效率没有生成控件高。优点就是,客户实现自定义功能较方便。
由于用子控件,大部分视图状态都可以交给webcontrol管理。
他对子控件的实现我认为不算太好,简单的控件都从一个基类派生,这点如果还算不上缺点,那么他对Forecolor等的实现方式,确实不算好。
总之cuteeditor是功能里面最强大的。但是他的实现,很难让人理解。不像Freetextbox,有中规中矩的实现。60分。
看了几个实现,可以说实现方式五花八门,除去视图状态不谈,只要把htmlrender到客户端,控件就算完成了。这就造成实现控件的方式很多。应该怎么写,确实值得思考。
Freetexbox,占去了大概一周的时间,这段时间我仔细看了他最新版本,以及更早版本的代码,它的实现和符合正常人的思路,很容易理解。对他的实现了解太多,以至于不想参考他的实现了。主要是怕写完代码和他特别像。从结构上来看,它的缺点我认为主要在于,把子控件的生成操作,都延迟到了父控件,造成父控件逻辑负杂。我最初的想法是,在Init的时候,构造一个xmldocument,然后每个子控件通过xml的方式,增加xmldoc的节点,最后再返回xmldoc给父控件。
Cuteeditor用了两三天的时间,他的代码很乱,几乎不符合常人的思路。尤其他为了防止破解,故意调整了几个类的顺序,如Editor,嵌套了四五层的内部类,让人看起来很头痛。从他的html看,也不像其他控件一样,能得到许多有用信息。
由于他的效果最好,并且我看了好久都没有头绪,觉定从他下手,写一个类似的editor。
其他的几个控件,和这两个相比都差很远,忽略。
经过近一个月的努力,控件开发终于过半,对cuteeditor的研究也更深入了,觉得他的许多实现确实很诡异,也让人眼前一亮。增加到80分。
Cuteeditor特点
首先,它对资源文件的处理方式来看,他没有采用.net的资源文件,也不是通过自己定义资源管理类来在用到资源时本地化。而是通过重写Textwriter的innerwriter和response的filter实现。细节上,他用到了Idispose接口和using语句,这样在缓冲去满,或者dispose时,自动实现资源的本地化。简直是绝了,我一直没有想过能这样用dispose和这样实现资源。
其次,对事件的处理,这也是cuteeditor做的很好的地方,它把所有的postbackdate和postbackevent,封装到了两个隐藏域中,这两个隐藏域是两个webcontrol,他的值为post的数据和事件。这就使新增事件及其简便。只要加上postback=ture,就可以处理回发。
其次,对脚本的管理,他的脚本都是动态加载的,因此不能调试。又是一个防止破解的招数。
通过httphandler,他托管了*.js的加载。
再次,配置文件的管理,他在运行时,会把几个配置文件加载到一个xmldoc中,实现统一管理。Js也实现了类似功能。
还有,Gizip,以及缓存的管理方式,都和一般人的不同,感兴趣的自己去看源码。
类似的诡异实现还有很多。
我写的editor,主要在下面几点做了改进:
首先是,子控件的管理上,他的管理方式不算好。我把类似ForeColor的控件都抽出了基类。
其次,我认为应该让客户更简单的自定义控件。因此在这点上也有改进。
再次,net2.0已有的功能不再自己实现,如Gizp,在2.o已经有了Gizpstream。
我希望用Ma.js重写他的客户端脚本,因此在服务器端尽量做些支持。
其中,界面满分20。cuteeditor和Radeditor都是20分。freetextbox10分
服务器端代码部分,ce60,freetextbox70,radeditore70。满分80