zoukankan      html  css  js  c++  java
  • 前端框架决择

    前端框架决择

    对于BS管理系统,我很长一段时间都工作在Asp.Net Web Form上,Web Form的主要优势是可以使用服务器端控件,以类似CS的开发模式进行工作,通过拖拽控件和定义事件处理函数,极大的简化了BS的开发。服务器端控件会在渲染阶段把自身输出为Html标签,对我们完全透明,当需要设置相关属性时,只需要在属性面板上操作即可。

      Web Form在诞生之时,Ajax还未流行,所以页面的提交是完全刷新方式。为了记住控件的状态,Web Form引入了ViewState和回发机制。对于一些复杂的界面,可能创建大量的服务端控件,查看ViewState序列化生成的hidden,有时候达到数百K。回发机制也让人郁闷,手工编写的Js与回发机制不能很好的配合,经常发现代码的执行时机不对。Web Form服务端控件生成的Html也相当杂乱,基本是面向机器的。

      当然这些问题很多时候是自己的使用方式不对,不能全赖到Web Form上,但大家希望.Net能够提供更好的解决方案。

      Ajax逐渐流行,对BS的要求大幅提升,比如局部刷新,干净整洁的Html等。一些 RIA框架发展起来,比如Ext、EasyUi、Dwz等。

      微软也推出了轻量级的Mvc框架,我是在Mvc 3 发布时才开始使用的,主要是被Razor视图引擎吸引过来。为了提升用户体验,还选择了一款RIA框架,当时选择了Dwz,主要是它开源免费,而其它框架要么闭源,要么收费,或者太复杂了,学习成本高。

      在使用了几年Dwz之后,最近决定更换一个前端框架,下面谈谈使用Dwz的一些情况。

      Dwz作为一款国产免费的开源框架是值得支持的,官网http://www.j-ui.com。通过Dwz,我学习到大量Js和Css的相关知识,在此表示感谢。

      Dwz基于JQuery,设计以Html扩展为主,对SPA (single page applications, 单页应用程序)有很好的支持,API命名规范,代码质量较高。

      使用中碰到的问题也不少,首先是缺乏专业的文档,官方只提供了一个很简单的使用手册,每当碰到问题,我总是进入dwz源码断点调试,不过这样更能深入学习内部机制,似乎也不算严重的缺点。

      从我开始使用Dwz,好像就没见更新过。

      Dwz有些组件不够完善,比如弹出模态窗口,只支持弹出一层,如果在弹出的模态窗口上继续弹出模态窗就不支持了,而这属于常用功能,对于这些小功能,我自己修改,咬咬牙也还是可以搞出来。

      对于一些重量级的组件,比如表格、树等,Dwz提供的比较弱,我一般都引入第三方插件,比如ZTree。

      还有一个头痛的问题是布局,Dwz没有提供border或fit这样易用的布局方式,除了面板和Tabs等常规布局组件外,只有一个神秘的layoutH属性,它的值是一个数字,表示工具栏的高度,对于一个复杂点的布局,我经常东调西试以找出这个正确的数字。当然这也只能怪我水平有限,掌握不够好,所以引入一个更强大的前端框架就迫在眉睫。

      对于大名鼎鼎的Ext,我已经关注它很长时间,不过一直没敢使用它,有几个原因。使用纯Js开发界面,有点违反一般程序员的习惯,大部分程序员还是喜欢用Html布局。另一个原因是面向对象的Js要求比较高,API丰富而庞大,学习成本高。当然最重要的一个原因是,对于管理后台这样的系统,大量手写Js开发效率低,且Js是弱类型语言,代码提示很弱,且没有编译时检查,容易出错,健壮性差。所以哪怕要使用Ext,我也会用C#来包装一次,这个工作已经有人做了,这就是Ext.Net。十分遗憾的是,Ext.Net不是开源的,而且还收费,它甚至把js等资源内嵌到dll中,另外还不支持DataAnnotations验证,这让我打消了使用它的念头。

      Ext也是要收费的,但有一个版本2.0.2可以免费使用,我的想法是,如果做小项目,就用高版本,偷偷的用估计也没人知道,如果需要公开使用,就切换到2.0.2这个版本。通过C#创建一个抽象机制,不仅可以简化开发,而且可以方便切换版本。我在尝试了一段时间后,发现封装的工作量很大,所以暂停了,待以后确实需要的时候再继续。

      目光转到EasyUi,EasyUi传说也是国人开发的,不过其官网却是纯英文。对于EasyUi,我几年前也曾了解过,当时认为没有源码,万一出现bug不是束手就擒吗。虽然如此,我却发现它越来越流行了,博客园搞框架的十有八九都是用的EasyUi,周边也有很多公司在使用,甚至在招聘要求上,我也看到过要求有EasyUi的经验。这说明EasyUi的稳定性还是有保证的,大家用都没问题,难道我的运气就那么背。

      除了跟风以外,我选择EasyUi还有几个重要原因,首先是功能比较强大,重要的复杂组件和布局组件都提供了,虽然没有Ext那么完善,但也基本够用。其次是学习成本低,EasyUi也是基于jQuery,而且支持Html扩展。最后是官方文档比较齐全。

      可以看到,EasyUi的功能、文档、易用性等介于Dwz与Ext之间。

      还有一些朋友给我强力推荐Bootstrap,不过我感觉它有点轻量,管理系统需要更重口味的框架,开发类似会员后台的时候再考虑采用Bootstrap。

      我学习EasyUi还不到一个月,很多东西仍处于摸索中,EasyUi虽然比较强大,但还是发现不少问题。

      首先是它的方法调用方式让人很郁闷。比如我现在要关闭一个窗口,需要这样调用$('#xxx').dialog('close'),为什么不能这样调用$('#xxx'). close ()。还好我主要使用Html扩展方式,手工编写Js仅用来处理回调,这个问题可以忍忍。

      其次发现不少小bug,比如多行文本框无法回车换行,时间控件在某些时候点击时报对象为null的错误等等,我使用的是IE 11,估计作者还没有对IE 11进行全面测试,希望能及时更新。

      EasyUi虽然是一个比较完善的前端框架,但并不意味着不需要花任何力气,你就可以开发出健壮的应用。下面讨论两个重要的设计决策。

    SPA还是IFrame

      SPA,全称Single Page Applications, 即单页应用程序。它的设计理念是仅在主框架界面使用一个完整的Html页面,其它所有内容页面都是Html片断,没有html、head、body这些标签,主框架界面通过ajax的方式加载内容页面。

      SPA是正宗的Ajax应用模式,并且逐步成为Ajax应用的趋势。它的优点显而易见,所有东西都在同一个页面,查找任何元素,直接用jQuery选择器就行了。

      任何事物都有两面性,SPA也有很多缺点,最严重是命名冲突和兼容性。

      对于同一个Html页面,如果两个元素的id出现重复,当你用css选择器进行格式化,或用jQuery选择器对其操作时,就会发生意想不到的情况。你会发现,操作某个内容页面时,居然影响到另外一个不相干的内容页。

      jQuery解决这种命名冲突,是通过传入一个额外的上下文对象,比如$(“#xx”,context)。Context代表某个内容页,这样就可以仅查找该内容页的id,从而消除了命名冲突。

      对于SPA,Dwz提供了天然的支持,它封装了CRUD相关的所有操作,并提供了一个当前上下文context来保存当前操作的内容页或弹出窗口。

      虽然Dwz提供了SPA支持,但我在使用中,依然发现偶尔出现各内容页互相影响的情况,为了防止命名冲突,我将id命名得很复杂,以减少冲突。

      再看EasyUi,对于CRUD操作,只在官网找到一个很简陋的Demo。仔细研究了Tabs等组件后,感觉EasyUi默认支持的是SPA模式,因为这些组件都没有对IFrame进行支持。EasyUi既然支持的是SPA模式,但却没有做进一步的封装,可以断定,以SPA模式使用EasyUi,命名冲突是比较严重的。

      还有一个头痛的问题是兼容性,由于所有内容页面在同一个Html中,如果某些页面需要引用一个第三方插件,而这个插件不是基于jQuery的,或者jQuery版本不同,引入这些插件可能失败。

      基于以往的经验,我决定不在管理系统这种复杂的应用中使用SPA,而是使用IFrame的方式加载内容页。

      由于EasyUi没有对IFrame提供支持,当我向主界面的Tabs引入IFrame后,引发了一大堆连锁问题,我花了大把时间终于把这些问题解决了,后面将用专门的文章来介绍碰到的障碍。

    封装有无必要

      大部分使用Mvc的朋友,都是从Web Form转过来的。所谓一遭被蛇咬,十年怕井绳,由于在Web Form上吃过过度封装的苦头,来到轻量级的Mvc世界,他们害怕服务器端的任何东西,只敢使用原生的html和js了。

      Mvc提供了一套Html表单控件的封装,比如文本框,@Html.TextBox( "id" ),它等价于<input type="text" name="id"/>。从这个简单的例子,好像使用服务器端语法优势并不明显。但值得注意的是,服务器端语法能够将DataAnnotations验证自动转化为jQuery验证,这一点还是比较强大的。

      对于简单的html标签,你是否使用mvc的服务端语法不是特别重要,但对于像Dwz或EasyUi这种Html扩展为主的前端框架就非常必要了。

      EasyUi将每个组件的属性都扩展到了Html标签上,对于Html标签,你还能指望代码提示吗?没有代码提示,就意味着你得随时打开EasyUi的官网,以复制相关的属性。当然你很多时候会自己手工输入,你必须把这些API记得非常精确,如果多一个或少一个字符,你就会得到错误的结果。如果你没有遵循敏捷开发的小步前进,而是把整个页面输入完成才开始运行,在密密麻麻的Html标签中找出输入错误的属性也不是一件容易的事。

      如果把EasyUi的属性用C#封装起来,由C#来输出Html标签,你就可以完全不再操心API的问题,所有的API只需在代码提示中上下移动即可。可以看到,Web Form的很多思想其实是非常好的,比如用服务端代码输出客户端代码,你应该去其糟粕,取其精华。

      对前端框架的封装,真正强大的地方来自Lambda表达式。

      从Lambda表达式中,你可以获取到一些元数据信息,比如name、value、验证信息,一个简单的操作@Html.EasyUi().TextBox( t => t.Name ),可能设置了10几个属性,并且所有的属性均来自服务器端,这样维护也更加方便了,你不用来回修改客户端代码。

      Lambda表达式还可以获取到属性的类型,这有什么用呢?当你写上一句@Html.EasyUi().TextBox( t => t.XXX ),如果XXX是整型,文本框就自动转成EasyUi的数字文本框,只能输入数字,如果它是一个日期,文本框就显示成一个日期控件。再比如@Html.EasyUi().Combox( t => t.XXX ),当它是布尔类型,就显示一个是、否的下拉列表,如果它是一个枚举就自动绑定一个枚举值的下拉列表,这是不是比你手工输入要强些呢。

    结语

      本文简要介绍了我对几个前端框架的认识,也说明了封装的必要性。

      由于我也是EasyUi初学者,我提供的Demo并不是一个可以直接使用的框架,不过作为学习范例,你可以把它作为你的应用程序框架的起点。

      我后续文章会逐步介绍Demo中各构造块的封装和使用要点,所有代码以我最新发放的Demo为准。

      为了不冲淡本系列主题,我会专门为EasyUi框架的封装创建一个系列。

      对于EasyUi的封装,我并没打算封装它的全部内容,毕竟我不是靠这个吃饭的,我仅在开发时碰到需求才会进行扩展,我的Demo会随着我的开发逐步增强,我会定期发放最新源码。

      Demo已更新,需要的老规矩,点推荐,留Email,本次截止201512815点。

      另外大家短时间没收到源码不要着急,只要在规定时间内都可以拿到。

      .Net应用程序框架交流QQ群: 386092459,欢迎有兴趣的朋友加入讨论。

      谢谢大家的持续关注,我的博客地址:http://www.cnblogs.com/xiadao521/

    版权所有,转载请注明出处 何镇汐的技术博客
     
  • 相关阅读:
    HDU 5640 King's Cake
    HDU 5615 Jam's math problem
    HDU 5610 Baby Ming and Weight lifting
    WHU1604 Play Apple 简单博弈
    HDU 1551 Cable master 二分
    CodeForces659C Tanya and Toys map
    Codeforces 960E 树dp
    gym 101485E 二分匹配
    Codeforces 961E 树状数组,思维
    Codeforces Round #473 (Div. 2) D 数学,贪心 F 线性基,模板
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/4255544.html
Copyright © 2011-2022 走看看