您的位置:首页 > 理论基础 > 计算机网络

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

2015-12-06 23:30 549 查看
  今天特别郁闷,怎么说呢,之前一直就用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:





静态方法与属性

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 转义得到适合在页面中显示的内容, 例如替换 < 为 <

currency(str,symbol),货币处理,默认第2个参数为¥

number(str,decimals, dec_point, thousands_sep),数字格式化。date(str, format),对日期进行格式化。str可以是毫秒数也可以是日期对象,format是诸如“YYYY MM dd HH:mm:ss”的格式
必需。要格式化的数字。

decimals 可选,规定多少个小数位。

dec_point 可选,规定用作小数点的字符串(默认为 . )。

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?",添加一个组件。
uiName,必选,一定要全部字母小写,表示组件的类型。

id 可选 这表示新生成的VM的$id,方便我们从avalon.vmodels[id]中获取它操作它。 如果它等于$,那么表示它是随机生成,与不写这个效果一样,框架会在uiName加上时间截,生成随机ID。

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, 接下来,看看如何使用它。

  待续。。。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: