轻量级mvvm Web开发框架 postby:http://zhutty.cnblogs.com

时间:2023-03-08 16:26:49

  今天特别郁闷,怎么说呢,之前一直就用angular,然后这两天用的是avalon这东西,反正,一开始没时间去玩它,第一个任务就是封装个jq插件,实现一个小功能。反正呢,就是越写越郁闷。用过angular的同学在去用jq应该都会有这种感觉吧。多此一举,费事。主要是,jq去一个一个操作dom树,把我搞郁闷了,最后,插件好了,但在一个地方用了好几次,这下好了,出问题了。问题像是这样的,晒出来供大家吐槽。

  

$.fn.PlaginName = function($){

      //这个插件实现的内容就是点击一个元素,然后发出一个ajax请求

}

/******我下面是在require中这样用的****/

$('.class1').PlaginName();

$('.class2').PlaginName();

$('.class3').PlaginName();

  大概就是这样吧,反正呢,结果就是,我三个地方随便一个地方点击事件,都会出发插件里的响应函数,导致请求了三次。这直接导致了我心塞了一下午。。。。。。。

  最后决定,放弃这个方案,既然都用了mvvm,干嘛还用这个低效率的jq呢。不过,有上述解决方案的童鞋,可以吐槽在评论。

  进入正题,其实jq已经很普及了,后来人们发现,项目大了,管理维护这一堆散散的代码,实在是蛋蛋的忧伤。于是应用了后端开发mvc思想到前端开发中。最先的前端mvc框架就是backbone了。不过,我只看了看它,听网友们的神吐槽说backbone使得代码量不降反增。我看了backbone写的那个todo list那个例子,确实有点繁琐。后来,借鉴了微软的wpf,于是出现了好多mvvm框架了,就是视图和模型双向绑定。最出名的就是angular了,*啊,有了它,你可以把jq丢垃圾桶了。不过,程序猿们有点不开心了,不为别的,就说性能。。。。。。然后挑刺,嫌angular太肥了,然后,各种剔除,改装。然后就有了avalon了,不过,这个东东,在我天朝还是有好些人在用的:好入手,快速开发。

  avalon官方地址:http://avalonjs.github.io/#home.html

  看看官方API:

轻量级mvvm Web开发框架 postby:http://zhutty.cnblogs.com

静态方法与属性

  • mix(a,b), 相当于jQuery.extend
  • vmodels, 用于放置生成的ViewModel
  • log(s), 打印日志
  • error(s),抛出异常
  • ui, 用于放置组件
  • noop, 一个空函数
  • ready(fn), domReady,将回调延迟到DOM树后才执行
  • oneObject(str|array, val?), 如果传入一个字符串则将它以逗号转换为一个字符串数组,否则一定要传字符串数组,第二个参数可选,为生成的对象的值。此方法是用于生成一个键名不一样,但键值都一样的对象。如{a:1,b:1,c:1,d:1}
  • type(obj), 返回传参的数据类型,值可能为array, date, object, json, number,string, null, undefined
  • isWindow(obj), 判定是否为window对象
  • isPlainObject(obj), 判定是否是一个朴素的javascript对象(Object),不是DOM对象,不是BOM对象,不是自定义类的实例。
  • slice(obj, start?, end?), 用于转换一个类数组对象为一个纯数组,后面两个为索引值,可以只取原对象的一部分元素。
  • range(start, end, step),生成一个整数数组,功能与underscorejs或python的同名函数一致。
  • bind(el, type, fn, phase),绑定事件,返回一个回调给你行卸载
  • unbind(el, type, fn, phase),卸载事件
  • each,功能同jQuery.each, 都是索引值或键名在前,值或元素在后
  • avalon.define(id?, factory),定义一个ViewModel
  • scan(element?, ViewModel?),开始扫描DOM树,抽取绑定。
  • define(id?, deps?, factory),一个全局方法,用于定义AMD规范的JS模块
  • require( deps, callback),一个全局方法,用于加载JS模块
  • css( node, name, value?),如果只有两个参数,读取元素的某个样式,三个参数时,设置元素某个样式
  • nextTick(fn),延迟执行某个函数,类似于setTimeout(fn, 0)
  • contains(a, b),判定A元素包含B元素
  • parseHTML(str),将一段字符串转换为文档碎片
  • innerHTML(node, str),对节点node进行innerHTML操作,在旧式IE下,head, table, td, tr, th等元素的innerHTML是只读,这个方法进行了兼容处理。
  • clearHTML(node),清空元素的所有子节点。

avalon.Array

  • remove(array, el),移除某个元素,成功返回true,失败返回false
  • removeAt(array, index),移除某个位置上的元素,成功返回true,失败返回false
  • ensure(array, el),只有数组不存在此元素时才添加它

另,avalon对Array.isArray上做了兼容处理,IE6也可以使用此方法

avalon.filters

各种过滤器

  • uppercase(str),全部大写
  • lowercase(str),全部小写
  • truncate(str, length, truncation),length,新字符串长度,truncation,新字符串的结尾的字段
  • camelize(str),驼峰化
  • escape(str),将字符串经过 html 转义得到适合在页面中显示的内容, 例如替换 < 为 &lt;
  • currency(str,symbol),货币处理,默认第2个参数为¥
  • number(str,decimals, dec_point, thousands_sep),数字格式化。date(str, format),对日期进行格式化。str可以是毫秒数也可以是日期对象,format是诸如“YYYY MM dd HH:mm:ss”的格式
    1. 必需。要格式化的数字。
    2. decimals 可选,规定多少个小数位。
    3. dec_point 可选,规定用作小数点的字符串(默认为 . )。
    4. thousands_sep 可选,规定用作千位分隔符的字符串(默认为 "," )。如果设置了该参数,那么所有其他参数都是必需的。
  •      'yyyy':   4 digit representation of year (e.g. AD 1 => 0001, AD 2010 => 2010)
    'yy': 2 digit representation of year, padded (00-99). (e.g. AD 2001 => 01, AD 2010 => 10)
    'y': 1 digit representation of year, e.g. (AD 1 => 1, AD 199 => 199)
    'MMMM': Month in year (January-December)
    'MMM': Month in year (Jan-Dec)
    'MM': Month in year, padded (01-12)
    'M': Month in year (1-12)
    'dd': Day in month, padded (01-31)
    'd': Day in month (1-31)
    'EEEE': Day in Week,(Sunday-Saturday)
    'EEE': Day in Week, (Sun-Sat)
    'HH': Hour in day, padded (00-23)
    'H': Hour in day (0-23)
    'hh': Hour in am/pm, padded (01-12)
    'h': Hour in am/pm, (1-12)
    'mm': Minute in hour, padded (00-59)
    'm': Minute in hour (0-59)
    'ss': Second in minute, padded (00-59)
    's': Second in minute (0-59)
    'a': am/pm marker
    'Z': 4 digit (+sign) representation of the timezone offset (-1200-+1200)
    •      format string can also be one of the following predefined localizable formats:
      
           'medium':     equivalent to 'MMM d, y h:mm:ss a' for en_US locale (e.g. Sep 3, 2010 12:05:08 pm)
      'short':   equivalent to 'M/d/yy h:mm a' for en_US locale (e.g. 9/3/10 12:05 pm)
      'fullDate':   equivalent to 'EEEE, MMMM d,y' for en_US locale (e.g. Friday, September 3, 2010)
      'longDate':   equivalent to 'MMMM d, y' for en_US locale (e.g. September 3, 2010
        'mediumDate':   equivalent to 'MMM d, y' for en_US locale (e.g. Sep 3, 2010)
      'shortDate':   equivalent to 'M/d/yy' for en_US locale (e.g. 9/3/10)
      'mediumTime':   equivalent to 'h:mm:ss a' for en_US locale (e.g. 12:05:08 pm)
      'shortTime':   equivalent to 'h:mm a' for en_US locale (e.g. 12:05 pm)

avalon.fn

要求传入一个元素节点或文档对象或window,你可以通过$().element, $()[0]再次访问到你传入的东西。它有以下原型方法。

  • hasClass(cls),判定有没有此类名
  • addClass(cls),只有元素不存在时才添加此类名(可同时添加多个)
  • remvoeClass(cls),移除多个类名
  • toggleClass(cls, state?),切换多个类名,如果第2个参数为布尔,则根据它强行添加或删除类名
  • attr(name,value?), 读写特性(此方法非常弱,直接使用setAttribute, getAttribute实现,没有做任何兼容性处理)
  • data(name, value?), 读写数据,使用HTML5的data-*特性实现。它会parse一下,让数据更为实用,思路同jQuery,如果一个传参也没有,将元素的data-*属性组成一个对象返回
  • removeData(name), 移除数据
  • css(name,value?),读写样式,这个兼容性做得很好,因为长达一百行,连HTML5的私有前缀都能你补上。
  • width(val?), 读写宽度,注意对隐藏元素没有处理。
  • height(val?), 读写高度,注意对隐藏元素没有处理。
  • bind(type, fn, phase),绑定事件,这个没有做链式操作,目的是为了返回回调给你卸载。
  • unbind(type,fn, phase),卸载事件。
  • val,读取表单元素的value值,功能同jQuery。
  • offset,取得元素在文档中的坐标,功能只实现了jQuery的一半,只能读不能写。
  • scrollLeft,取得水平滚动条的位置。
  • scrollTop,取得垂直滚动条的位置。

各种绑定

  • ms-html="str", 设置innerHTML,会清空此元素下的所有节点
  • ms-class="className:boolean", 切换类名
  • ms-hover="className", 移上去时添加这类名,移出去掉。
  • ms-active="className", 获得焦点添加这类名,失去焦点去掉。
  • ms-visible="boolean", 操作元素的style.display实现显示隐藏
  • ms-if="boolean", 决定是将此元素放出到DOM树还是移出
  • ms-each-el?="array", el用于下面的引用。在它的作用范围,你还可以访问$index得到其索引值,$first判定是否第一个元素,$last是否最后一个,$remove为一个方法,你执行它就会从数组中删除它,并将它作用的那一片元素都移出DOM树。
  • ms-duplex="property",只能用于表单元素,与ViewModel中的某些字段双向绑定,它会偷偷绑定一些事件进行同步。
  • ms-controller="ViewModelName",指定一个ViewModel的作用范围
  • ms-important="ViewModelName",指定这个区域只能由这个ViewModel来渲染
  • ms-skip,不对此元素及后代进行扫描绑定,保证原样输出。
  • ms-on-type="callback",绑定一个事件,type为事件名,如ms-on-click="tick"。什么ms-click, ms-focus, ms-keyup, ms-keydown都是由它衍生出来的。
  • ms-click="callback",ms-keypress="callback",ms-keydown="callback", ms-keyup="callback",ms-mousedown="callback"……等常用事件都做了一个快捷方式。
  • ms-href, ms-alt, ms-src, ms-title,ms-value这些绑定的属性如果不带有{{ }},则以其他绑定一样,直接eval属性值, 然后设置href, alt, src, title, value等属性,如果带有着{{ }},那么整个将变成插值表达式,返回一个文本,然后赋给相关属性。
  • ms-css-xxx="val",规则同ms-href,不同的是, 它赋值是使用css方法,即avalon(element).css(xxx, val)
  • ms-disabled,ms-readyonly,ms-selected,ms-checked等布尔属性,根据属性值的情况决定添加与移除
  • ms-enabled="boolean",与ms-disabled相反。
  • {{ expr }}, 插值表达式,与angular相同,可以使用“|filter(args1, args2)”的形式添加多个过滤器。
  • {{ expr|html }}, 相当于ms-html,但不会影响它的兄弟节点。
  • ms-widget="name, id?, opts?",添加一个组件。
    1. uiName,必选,一定要全部字母小写,表示组件的类型。
    2. id 可选 这表示新生成的VM的$id,方便我们从avalon.vmodels[id]中获取它操作它。 如果它等于$,那么表示它是随机生成,与不写这个效果一样,框架会在uiName加上时间截,生成随机ID。
    3. optName 可选, 配置对象的名字。指在已有的VM中定义一个对象(最好指定它为不可监控的外),作为配置的一部分(因为每个UI都有它的默认配置对象,并且我们也可以用data- uiName? -xxx来做更个性化的处理 )。如果不指optName默认与uiName同名。 框架总是找离它(定义ms-widget的那个元素节点)最近的那个VM来取这个配置项。

ViewModel

  • 与angular的要求一致,$开头的为框架所保留,由于在IE6-8中然后VBS实现,无法区分大小写,不要同一个ViewModel定义两个近似的方法名。
  • $id为ViewModle的名字
  • $events为一个对象,用于保存$watch方法的回调
  • $watch(prop, callback),ViewModel只能通知它的视图进行更新,不能通知他在ViewModel的其他属性,对于监控属性,我们可能通过这方法实现兄弟间的通信。
  • $unwatch(prop,callback?),停止通知
  • $model,对应ViewModel的普通javascript对象形式(早期的版本,它是叫做$json)
  • 以$开头的属性,框架都不会将它转换为监控属性
  • 放在$skipArray中的属性名,也不会转换为监控属性
  • 一个包含get与set的对象被认为是一个计算属性。

以上这部分是官网的api, 接下来,看看如何使用它。

  待续。。。。。