咸鱼的翻身技术

JAVA/JAVASCRIPT

参与水母万J版的讨论记录

Title发信人: withinsea (沐海~魔導奏器|歌の琴フォルテール), 信区: Java
标  题: [jq] 稍微谈一点 jquery-ui 的 widget 框架
发信站: 水木社区 (Thu May 13 09:15:23 2010), 站内

最 近版上又有人提到过新的 js 的页面组件框架,都是不错的东西
不过作为 jq 的坚定用户,也来稍微写一点 jquery-ui 自己的 widget 特点
因为 jq 不管是做为一个基础库还是作为一个 widget 框架都还是相当风格独特的
随便写几句,不多铺垫感情 了,直接列重点……

=== 共同点 ===

widget 类的定义、命名
继承已有的 widget 类
widget 的创建、刷新、销毁等生命周期
自定义的事件触发/响应机制
这些 widget 框架的基本功能都是有的,不再赘述

=== 主要区别 ===

  [一般框架]                          [jquery-ui]

  创建 widget 的过程中生成元素        先提供元素,然后向其上附着 widget
  widget 是一组元素及其属性和行为     widget 是附在元素上的一组属性与行为
  一组元素是一个 widget               一组元素上可以附着多个 widget

一般 widget 框架的结构大多类似桌面 gui 程序的结构
我给定一些参数,通过 这些参数实例化一个 widget 类,并创建一系列元素
从而形成页面的上的功能组件

这些参数的提供方式多种多样
主要包 括 特定的元素属性(extjs)、特定的元素名(dojo) 以及 js 手动构造 三种
这些代码风格的区别决定了框架的易用程度,但本质都是 相似的

相对的,jquery-ui 的很多 widget(虽然官方的实在没多少……)则是相当抽象的
widget 构造函数很可能不创建任何元素,而只是向原有元素上添加一系列的属性、事件
从而使这些元素具有 widget 所需要的功能

这种 设计的一个直接结果是,只要两个 widget 所占用的属性、事件等没有冲突
那么同一个元素同时作为多个不同的 widget 存在是完全正常的
——举例来说,你想要一个 可以拖动边框更改大小的进度条,这是一个很自然的需求
但你并不需要在编写 ProgressBar 这个 widget 的时候继承与 resize 有关的代码
你只需要在同一个元素上同时启用 ProgressBar 和 Resizable 两个 widget 就可以了

这就好像你在使用一个支持多继承的语言来构建 ui 框架
只不过多继承 的进行不是在 widget 的编写阶段,而是在运行时完成的

=== 优缺点 ===

[优点]

1. 独立,可大可小

   每一个 widget 就是一个独立的插件
   除了 jquery-ui 提供了一些创建插件的工具方法之外
   jq 的 widget 和 jq 的 plugin 并没有什么本质区别
 
   所以除非主动去继承,否则每一个 widget 之间都相当独立
   编写一个足够大的 widget 库当然是可以的;
   但如果你只需要一个简单的 widget,编写一个就是了
   不会有一坨的 Component, Container, GridItem 之类基础类需要你去继承

2. 对 html coder 友好

   既然 widget 只是附加到元素上的附属品
   那么 html coder 和美工就没有必要等待你的 widget 生成了足够的元素再去调试
   作为 html 开发和 widget 开发分离的结果
   界面的设计是比较容易进行的
   毕竟他们在美化的是传统的页面,而不是 widget 生成的元素汤;
   因此你也不会拿到一套永远只能生成一种风格界面的 widget 库

   当然另一方面来说,这对 widget 编写者提出了更高的要求
   你不能乱改 html 结构,你不能随便包一堆 wrapper,你不能滥用无数 tricks...
   但是,本来就只有这样的 widget 才是好的 widget,不是么?

[缺点]

1. 易于冲突,难于设计

   同一个元素可以绑定多个 widget 这一机制很强大
   但是相对的,它也没有任何能力去自动防止两个 widget 产生冲突
   你必须自己避免这件事

   举例来说,resizable 这个 widget 会在元素里添加一个拖动用的 handler 元素
   如果你要在这个元素上绑定其它 widget 的话,小心不要把这个 handler 删掉

2. 命名空间能力贫乏

   最大的问题,jquery-ui 现阶段基本上没有命名空间能力……
   默认的 widget 命名类似 ui.dialog 这样,并允许你使用 my.dialog 这样的命名
   但实际上,这个 ui. 还是 my. 完全不起作用
   无论是 ui.dialog 还是 my.dialog,都会绑定到同一个插件 .dialog() 上
   widget 对象实例化后也会用同一个名字 dialog 绑定到元素上
   其结果就是这两个看似不同命名空间的 widget 根本就是冲突的,没办法同时使用

   至于更多级的命名空间,比如 my.widgets.dialog 之类,干脆就不支持

   这问题带来的直接结果就是用它构建大规模的组件库会为命名相当头疼
   基本上你只能使用 my_widgets_dialog 之类的方法去折衷
   虽然也不是完全没法用吧
   我想 jquery 只是还没能找到让多级命名空间和 plugin 保持风格一致的方法
   当然这方法有没有还是个问题……
   ui.dialog 对应插件 $(...).dialog() 上的话,多级的又该写成什么样子好?

3. 缺少 import/require 之类的库管理机制

   jquery 到现在为止都没有推出过插件命名的标准建议
   既然文件名字没准谱,那么 import 函数之类自然也就没法写
 
   不过,手工补上这个功能也还是很容易的——
   你自己的类库的话,自然有你自己固定的命名风格

4. 缺少 widget 初始化的语法糖

   上面说过的,通过特定属性或者特定元素名自动初始化 widget 的机制
   jquery... 其实不是没有,但只是一个非常内部的 api (jquery.metadata)
   看上去也没有暴露出来公开使用的打算
   这很难说是一个缺陷还是一个设计
   因为 jquery-ui 默认也不是为了把整个页面都变成 desk-like 而设计的

   当然,同样的,这一机制也很容易被手工补上。下面这个风格是我在使用的:

     <div data-jq-resizable="{ handles: 'e' }">...</div>

  (等价于 $(...).resizable({ handles: 'e' }); )

=== 例子 ===

一个简单的代码风格 演示。创建了一个能够切换多个状态的开关
只是个演示的缘故,没有做什么无效参数检查之类

// 编写 widget

  $.widget('multi_switch', {

    options: {
      statuses: [ 'on', 'off' ]
    },

    _statusIdx: -1,

    _create: {
      var el = $(this.element);
      el.click(function () {
        $(this).multi_switch('next');
      });
      this.next();
    },

    next: function () {
      var el = $(this.element), o = this.options;
      if (this._statusIdx >= 0) {
        el.removeClass(o.statuses[this._statusIdx]);
      }
      this._statusIdx = (this._statusIdx + 1) % o.statuses.length;
      el.addClass(o.statuses[this._statusIdx]);
    }

  });

// 准备 html 元素

  <style type="text/css">
    input.full     { background: white; }
    input.half     { background: silver; }
    input.crescent { background: gray; }
  </style>

  <input id="demo_switch" type="button" />

// 创建 widget

  $(function () {

     $('#demo_switch').multi_switch({
       statuses: [ 'full', 'half', 'crescent' ]
     });

  });

--
我 渴望得到幸福 我渴望得到幸福 和你一起得到幸福 成为你的幸福
请带我离开 远远的带我走 离开这个地方
小鸟们唱着 听不懂的诗歌 长着 翅膀也不能 在空中翱翔
独自一人无法到达的地方


※ 修改:·withinsea 于 May 13 10:16:22 2010 修改本文·[FROM: 221.221.163.174]
※ 来源:·水木社区 newsmth.net·[FROM: 221.221.163.174]


Title发信人: hopesfish (有理想的咸鱼), 信区: Java
标  题: Re: [jq] 稍微谈一点 jquery-ui 的 widget 框架
发信站: 水木社区 (Thu May 13 15:18:28 2010), 站内

我个人认为,ui框架应 该依托项目而生,除了提供基础的widget,还应该基于项目特点封装一些widget,减少参数的配置,因为config的参数太灵活了,非前端程序员 对js的灵活性又不是掌控的很好...稍不注意就会带来开发和维护的成本

对于基础widget,可以奉行拿来主义,也可以奉行独立开发, 毕竟后者对中小型项目的灵活性还是有很大的支援...但是这种灵活性又要一定的测试体系做保证,但是前端的自动化测试,ms还没有一个特别好的解决办 法..

非常同意你认为组件是基于html的附属品,ext俨然就是另外一个极端,html的生成也包揽了,尤其是现在还出了一个ext designer,在局域网应用的市场会更广阔...

但是我觉得除了保证widget库丰富性的同时,还应该关注组件自身的单元测试,组 件间的消息机制,也就是降低耦合度...ms这几个现在也很潮...

最后就是那个Scalable JavaScript Application Architecture,说完美的框架是不用知道底层的库是什么实现 如jq/ext core/yui core之类的。。。然后基于这个框架做上层的应用我就想...这些ext早期的adapter不是一个玩意么?呵呵


Title发信人: canper (洗衣粉), 信区: Java
标  题: Re: [jq] 稍微谈一点 jquery-ui 的 widget 框架
发信站: 水木社区 (Thu May 13 15:26:00 2010), 站内


 ext那种模式本来就只适用 于内部系统,不适合适用于互联网应用

Title发信人: hopesfish (有理想的咸鱼), 信区: Java
标  题: Re: [jq] 稍微谈一点 jquery-ui 的 widget 框架
发信站: 水木社区 (Thu May 13 15:29:50 2010), 站内

早期出来的时候还有支持 html生成的 因为有yui2的影子
到了后期写js写high了...
我朋友里面用ext做应用界面...就剩下body光秃秃 了...美工纷纷表示苦不堪言。。。

Title发信人: modico ().net(), 信区: Java
标  题: Re: [jq] 稍微谈一点 jquery-ui 的 widget 框架
发信站: 水木社区 (Thu May 13 15:31:10 2010), 站内

 我一开始也是“组件是 基于html的附属品”路线,后来自觉反过来了。..

Title发信人: hopesfish (有理想的咸鱼), 信区: Java
标  题: Re: [jq] 稍微谈一点 jquery-ui 的 widget 框架
发信站: 水木社区 (Thu May 13 15:32:28 2010), 站内

主要内容还是要html 吧 提高交互体验的..还是乖乖的用组件生成html吧

Title发信人: canper (洗衣粉), 信区: Java
标  题: Re: [jq] 稍微谈一点 jquery-ui 的 widget 框架
发信站: 水木社区 (Thu May 13 15:34:39 2010), 站内


   所以不用form部分,那部分全用js生成就太过了

Title发信人: modico ().net(), 信区: Java
标  题: Re: [jq] 稍微谈一点 jquery-ui 的 widget 框架
发信站: 水木社区 (Thu May 13 15:38:27 2010), 站内

 美工经常问:can i help you?

Title发信人: hopesfish (有理想的咸鱼), 信区: Java
标  题: Re: [jq] 稍微谈一点 jquery-ui 的 widget 框架
发信站: 水木社区 (Thu May 13 15:39:50 2010), 站内

其实美工还好 如果没有限制 天马行空搞一把就好了
然后就该页面工程师(如果和美工不是同一个人的话)哭了。。。
【 在 modico ().net() 的大作中提到: 】


Title发信人: withinsea (沐海~魔導奏器|歌の琴フォルテール), 信区: Java
标  题: Re: [jq] 稍微谈一点 jquery-ui 的 widget 框架
发信站: 水木社区 (Thu May 13 16:56:53 2010), 站内


【 在 hopesfish (有理想的咸鱼) 的大作中提到: 】
: 我个人认为,ui框架应该依托项目而生,除了提供基础的widget,还应该基于项目特点封装一些widget,减少参数的配置,因为config的参数 太灵活了,非前端程序员对js的灵活性又不是掌控的很好...稍不注意就会带来开发和维护的成本
是的,提供一层基础的 widget,再封装一层具体的 widget,这样很好
比如提供基础的 resizable,封装出的可能是 dialog, dock, window layout
提供基础的 tab,封装出的可能是 tab panel, menu, image slider
提供基础 的 dock,封装出的可能是 toolbar, sidebar, border layout...
从这个意义上来说 jq-ui 和 extjs 其实不在同一层上……
组件框架 和 组件库 的区别

很多具体的 widget 在抽象意义上其实很相似的……
是 extjs 这种自成一套的大块头还好
很多网上的独立组件,各自为战的情况下重复代码实在相当的多
而渲染风格不同又让这些组件很难往一 个页面拼
这种时候,如果能有一个比较基础的组件框架可以遵循,情况就会好得多

: 对于基础widget,可以奉行拿来主义,也可以奉行独立开发,毕竟后者对中小型项目的灵活性还是有很大的支援...但是这种灵活性又要一定的测试体系做 保证,但是前端的自动化测试,ms还没有一个特别好的解决办法..
: 非常同意你认为组件是基于html的附属品,ext俨然就是另外一个极端,html的生成也包揽了,尤其是现在还出了一个ext designer,在局域网应用的市场会更广阔...
到 designer 这一步其实等于放弃直接编码了……
具体生成结 果是啥倒是确实无所谓

不过真打算彻底这么干的话何不直接上 flash/dotnet....

: 但是我觉得除了保证widget库丰富性的同时,还应该关注组件自身的单元测试,组件间的消息机制,也就是降低耦合度...ms这几个现在也很潮...
: 最后就是那个Scalable JavaScript Application Architecture,说完美的框架是不用知道底层的库是什么实现 如jq/ext core/yui core之类的。。。然后基于这个框架做上层的应用我就想...这些ext早期的adapter不是一个玩意么?呵呵

posted on 2010-05-14 12:23 hopesfish 阅读(68) 评论(0)  编辑 收藏 引用 所属分类: 胡思乱想

只有注册用户登录后才能发表评论。