vue,angular,avalon这三种mvvm模式框架之间有什么优缺点

以下内容是参考官方文档说明总结而来:Vue.jsVue.js
老师写的一个用于创建 web 交互界面的库,是一个精简的 MVVM。从技术角度讲,Vue.js 专注于 MVVM 模型的
层。它通过双向数据绑定把
层连接了起来。实际的 DOM 封装和输出格式都被抽象为了 和 。Vue.js和其他库相比是一个小而美的库,作者的主要目的是通过一个尽量简单的 API 产生可反映的数据绑定和可组合的视图组件,感觉作者的思路非常清晰。优点:简单:官方文档很清晰,比 Angular 简单易学。快速:异步批处理方式更新 DOM。组合:用解耦的、可复用的组件组合你的应用程序。紧凑:~18kb min+gzip,且无依赖。强大:表达式 & 无需声明依赖的可推导属性 (computed properties)。对模块友好:可以通过 NPM、Bower 或 Duo 安装,不强迫你所有的代码都遵循 Angular 的各种规定,使用场景更加灵活。缺点:新生儿:Vue.js是一个新的项目,日发布的版本,目前github上面最新的是版本,没有angular那么成熟。影响度不是很大:google了一下,有关于Vue.js多样性或者说丰富性少于其他一些有名的库。不支持IE8:哈哈不过AngularJS 1.3也抛弃了对IE8的支持,但是
老师的avalon是支持IE6+的,应该下了很多努力去优化。这一点对于那些需要支持IE8的项目就不好了,不过这也是web前端开发的一个趋势,像IE低版本就应该退出历史舞台了,通过改变我们的前端思维,而不是顺应那些使用老版本而不去升级的人。 老师就说过一句话,我觉得说的非常好“这年头,支持 IE6、7 早就不再是特性,而是耻辱。努力推动支付宝全面不支持 IE6、7,期待更多兄弟加盟”。 AngularJSAngularJS最近很火,追随者也很多。官方说得很朴素:“完全使用JavaScript编写的客户端技术。同其他历史悠久的Web技术(HTML、CSS和JavaScript)配合使用,使Web应用开发比以往更简单、更快捷“。当你学习它的时候,我相信你会被它的很多新特效所吸引。优点:动态视图:以前从来没有想过js可以如此扩展HTML的属性,但是AngularJs做到了,它替我们静态的HTML加了很多扩展性功能,有一种让HTML由死变活的感觉。完善:是一个比较完善的前端MVW框架,包含模板,数据双向绑定,路由,模块化,服务,依赖注入等所有功能,模板功能强大丰富,并且是声明式的,自带了丰富的 Angular 指令。Google维护:AngularJS有Google来维护,无疑有了一个强大的后台,对于推广和维护明显比Vue.js和avalon有优势,社区也非常活泼,能够很好促进它的发展。AngularJS & Ionic:,这俩就是一个好基友,Ionic通过用AngularJS为了创建一个框架,最适合开发的丰富和强大的应用程序。上次于知乎答了一个相关问题,详细可以见这里。缺点:大而全:学习起来有难度,对于我来讲学习曲线很曲折,比较难理解一些。推翻重写:前段时候逛社区发现AngularJS2.0会把之前的推翻重写,两个框架的改变很大,基本是两个框架了,等于是说等到2.0出来后又需要从头开始,不过又说回来, 老师的这篇文章很好说明了AngularJS2.0的变化。不支持IE8以下,貌似2.0变得只支持移动端了,等到出来后再看吧。Avalon.jsAvalon.js是
老师所写的个简单易用迷你的MVVM框架,它最早发布于,为解决同一业务逻辑存在各种视图呈现而开发出来的。常常可以看到老师推广他的Avalon.js,出了很多教程,无疑对国内学习Avalon.js的人提供了巨大方便。优点使用简单,在HTML中添加绑定,在JS中用avalon.define定义ViewModel,再调用avalon.scan方法,它就能动了!兼容到 IE6 (其他MVVM框架,KnockoutJS(IE6), AngularJS(IE9), EmberJS(IE8), WinJS(IE9) ),另有avalon.mobile,它可以更高效地运行于IE10等新版本浏览器中没有任何依赖,不到5000行,压缩后不到50KiB支持管道符风格的过滤函数,方便格式化输出局部刷新的颗粒度已细化到一个文本节点,特性节点要操作的节点,在第一次扫描就与视图刷新函数相绑定,并缓存起来,因此没有选择器出场的余地。让DOM操作的代码近乎绝迹使用类似CSS的重叠覆盖机制,让各个ViewModel分区交替地渲染页面节点移除时,智能卸载对应的视图刷新函数,节约内存操作数据即操作DOM,对ViewModel的操作都会同步到View与Model去自带AMD模块加载器,省得与其他加载器进行整合。缺点缺点可以看这里终于答完了,还有一些我没有找到的还有错误的希望大家指出。
avalon说的是WPF吗WPF在2000年的时候就叫avalon。从实现的角度上来讲,angular和WPF的data binding分别是pull和push模式。不过angular在那么慢的浏览器上做pull,WPF在高速环境下用push,性能肯定没法相比。
vue主打轻量级,仅作为MV*中的视图部分使用,优点轻量级,易学易用,缺点是大项目的时候还要配合其他框架或者库来使用,比较麻烦;AngularJS包含MV*中的所有部分,有自己的一套规则,写出来的代码结构会比较清晰,同时谷歌大厂出品,社区比较活跃,各种第三方插件比较多,缺点则是大家都在黑的性能问题,以及越来越像JSP的语法(看看AtScript的语法,越来越像Java了);Avalon没用过,听说对旧版IE支持程度较高,具体的细节可以直接艾特询问框架作者正美
[前端](http://tw93.github.io/)今年六月就要毕业了。不喜欢通信这个行业(可能我看的比较浅),因为感觉我们能做的只有网规网优或技术支持,这些工作太无聊太消磨斗志了。我一直对计算机和手机方面比较感兴趣(当初选通信也是家长做主自己随便的结果),特别是计算机软件和手机软件方面。所以想毕业找这方面的工作。可是大学期间没有接触Java,安卓开发等方面的知识!只学了简单的c语言。我该怎么制定学习计划(比如要学什么方面,java,php,Ql?先选择怎样的职位?)。还有一点就是我对我这个通讯专业的就业认识是否准确(有哪些工作其实不是那么死板又是我们专业可以胜任的)?
怎么你们每个人都是说什么父母选的专业?明明是自己不行,把一切责任都推给父母,推给学校,推给社会,推给政府,推给国家,然后呢?然后你就行了?你首先得承认,选专业失败你起码占大部分责任。而且你父母也没有在大学期间把刀架在你脖子上逼你不准看编程书搞编程,你玩游戏看电影撸管子的时候,也没有想过要好好看书。知乎这种问题都说烂了,TM的能不能做一个警告,顺便提重复问题的时候直接给提问人定向到搜索结果页面啊所以,你得先承认自己失败的过往,然后手起刀落和过去一刀两断,学会搜索,这样才能重新做人
"我的时间很宝贵,你应该心存感激"这种话都说得出口。。。即便你混得比别人好,不代表你就有资格教训别人。人生在世,有太多的因素影响着,客观原因才是真正的原因。你以为你努力是所谓的个人意志的体现?你的"努力"这个品性本身都是之前客观事实的结果。有什么是天生的?若有,你天生优越,这更是客观事实,你携带更好的基因血统,你不过比别人幸运罢了。题主问题或许小白,但只要是真诚的提问,就不应被冷嘲热讽。
利益相关:西安电子科技大学通信工程学院大四狗本人也不是很喜欢通信方面的专业,虽然通信专业成绩还算好,但是大三大四的成绩基本上也是为了考试不挂科才去学习的,没有熟人,逃。。。。这里我把踩过的坑和楼主一讲吧。我们专业大一下有一门叫做数据库的课程,从那时候起踏入了互联网开发的大坑。因为喜欢这方面,然后就去图书馆找书看,敲代码。到了大二的时候在西安小公司实习,做做web开发的外包项目,然后就慢慢走上在学校接外包的不归路。。到了大四,放弃了学院的保研,选择了工作,工作没有找好,不说了,不过是自己喜欢的做web前端开发。下面是建议:既然选择了想往移动互联网行业发展,那么就去做吧,不要纠结了,很多事情越纠结越不能做好,移动互联网这个行业有很多职位,有客户端开发,web开发,还有一些非技术方面的职位(产品经理,游戏策划等),你说你喜欢计算机软件和手机软件方面。那就想想自己到底要做什么吧。假如选择Web方向,可以向下看,不是就折叠吧。通信专业的学生其实转程序开发也不是很难,毕竟有一些计算机方面的基础,只要肯学习,应该不会很难。第一步是学会搜索,善用google,stackoverflow.这一些搜索工具,你在编程练习过程中遇到的问题基本上可以找到答案。假如打算web开发,选择是做前端还是后台,那么首先还是的了解Html/CSS基础,这里直接看就可以了,没有必要记住每一个,入门时候只需要知道怎么用,怎么查就可以了,这里大概会消耗一天时间。然后就是模仿,找一些网上的静态页面模仿出来(知乎上面好多这样的问答,如何学好什么什么。。。学会搜索)。基本掌握后,既可以学习JavaScript,这是web前端开发的重头戏,看书吧,好好啃《JavaScript高级程序设计》,我觉得这本书很好,这里会消耗你很多时间,对于前端开发面试这里问得很多。接着又是模仿,模仿有那种JavaScript特效的页面。以上这些我觉得不管是做前端还是后台都必须了解的。---------------------更新-------------------------------------------------------------------------------对于前端发展:继续学习JavaScript,学习去使用一些库,初级的可以去学习jQuery(write less do more)学完这个js库后,你会发现原来写JavaScript是如此简单快速之后可以学习Bootstrap这个框架,用好了以后,你做页面会很轻松的(黑外包就常常用这个框架,当你记住了每一个使用的方法,真的好快)。中期可以学习AngularJs其他MVVM框架,这里有个我以前的回答,我最近也啃AngularJs的官方文档,的确是一个很强大的MVVM框架。假如想体会下写后台的乐趣,可以学习Nodejs,Nodejs是上帝送给前端工程师最好的礼物。后期,没有资格提建议。11. 对于后台发展:这里你需要选择一个后台开发语言,这个具体看自己的决定,PHP,Python,Nodejs,Ruby知乎上面有很多关于这些语言对比的问答,你可以去搜索。这里的学习我认为可以找官方文档去学习,之后可以看一看业内大牛们比较推荐的书籍。之后可以学习它们的一些强大的框架,如PHP的symfony框架(上次做商业项目时候临时去啃的官网文档,很详细,项目做完后,真心觉得这个框架很强大),Python的flask框架(看别人用过,python很优雅,自己不会python....没有建议),还有Nodejs的Express框架(用过,很优雅,自己想往Nodejs方向发展,太爱),最后是Ruby on Rails这个(也只是了解)。同时你还需要学习数据库,有关系型数据库MySQL,这个数据库用得很多;还有NoSQL数据库这一类型的数据库(使用过MongoDB,改变了我对原来数据库的印象)。对于后期发展我也没有对应建议,这里我也是入门而已。12. 然后就去找工作吧,找工作时候,好好准备简历,网上写简历技巧很多,自己去google,同时要对简历上面自己写的东西很了解,应届毕业生就不要写精通什么什么,但是你的简历又要展示自己的能力,让面试官觉得你是I Want To You的人选,还有你做的项目是你的一个加分项。最后应届生找工作,如果是开发工程师,c语言不能丢,c语言不能丢,c语言不能丢,c语言不能丢,c语言不能丢,算法不能丢,算法不能丢,算法不能丢,算法不能丢,算法不能丢,算法不能丢,算法不能丢,算法不能丢,算法不能丢,算法不能丢。--------5月21日更新------最后去了一个自己满意的互联网公司。
o??俺在网上有超能力当前访客身份:游客 [
当前位置:
迷你MVVM框架 avalonjs 1.2 发布
avalon1.2 带来了许多新特性,让开发更轻松!详见如下:
升级路由系统与分页组件。
对ms-duplex的绑定值进行增强,以前只能prop或prop.prop2,现在可以prop[&xxx&]、prop[prop2]。换言之,添加对数组法对子属性的支持。详见
ms-duplex支持用JS修改input.value触发oninput事件(实现旧式IE下onpropertychange的功能),实现大量第三方组件都会操作input.value,有了这功能,我们就不需要写额外回调实现对VM对应属性的同步,从而加强与第三方组件的整合能力。详见与
让ms-repeat, ms-with在目标都是对象的情况下支持data-with-sorted回调。详见
添加data-widget-defined回调,this指向绑定元素,参数为新生成的VM对象。详见
avalon在移除ms-controller, ms-important绑定的同时,现在会移除与其同名的类名,这是为了兼容IE6。(关于网速慢,{{}}插值表达式暴露出来的问题, 我们可以定义这样一个样式规则进行处理[ms-controller],[ms-important]{display:none} 为有点类于angularjs的ng-cloak指令,在扫描之前起着羞丑布的作用。对于IE6不支持属性选择器的问题,只能手动处理,或使用ms-text来代替{{}},这视你的用户群体决定了——)
重构parseExpr内部方法。
重构AMD加载器获取相对于父路径的逻辑。
重构parseData内部方法。详见
avalon.require.text模块尝试使用HTML Imports技术加载子页面与模板文件。详见
fix ms-if 当第一次没有定义某属性进行隐藏后,然后再替换整个对象,让它拥有此属性时,注释节点重复生成引发的BUG。 详见
fix nextTick在IE6下崩溃的BUG。详见
fix DOMReady在移动端如果网速过慢,不会触发的BUG。详见
移除为input添加name的特性。因为浏览器会提交拥有name属性并且没有定义disabled属性的表单元素。私自为它添加name,会打破用户原来的意图。详见
迷你MVVM框架在github的仓库官网地址
有关avalon的最佳实践或注意点请看, 这个我每次发布新版本都可能在这里加东西。
使用avalon做的东西:
(帐号:crm_ceo 密码:nncb_ceo)
Avalon 的详细介绍:
Avalon 的下载地址:
想通过手机客户端(支持 Android、iPhone 和 Windows Phone)访问开源中国:
旧一篇: 1年前
新一篇: 1年前
相关讨论话题
你也许会喜欢
这类只能在内网使用,跟angular一样,太重了。第一次打开页面下载几百K的身躯。不如jquery轻巧与速度。
2楼:bobshi
引用来自“岭南才子”的评论这类只能在内网使用,跟angular一样,太重了。第一次打开页面下载几百K的身躯。不如jquery轻巧与速度。你竟然说angular重。。。
3楼:头号大宝贝
看了cnbootstrap的例子,我整个人都不好了。/base-css.html简直就是愤青……
4楼:开源码农
引用来自“头号大宝贝”的评论看了cnbootstrap的例子,我整个人都不好了。/base-css.html简直就是愤青……太认真的了不好,人家都是去看例子的,你全去看文字
5楼:xesam
引用来自“岭南才子”的评论这类只能在内网使用,跟angular一样,太重了。第一次打开页面下载几百K的身躯。不如jquery轻巧与速度。jquery跟这是两码事,jquery顶多就是兼容库,这都是框架。
6楼:ForJustice 来自
一直在关注,还不够稳定
7楼:sulinixl
简单看了一下,太粗糙了吧?
8楼:苏生不惑
oscer用过吗?正学angular呢
9楼:se77en 来自
引用来自“xesam”的评论引用来自“岭南才子”的评论这类只能在内网使用,跟angular一样,太重了。第一次打开页面下载几百K的身躯。不如jquery轻巧与速度。jquery跟这是两码事,jquery顶多就是兼容库,这都是框架。确实,jquery不算框架
10楼:gzwxn 来自
引用来自“头号大宝贝”的评论看了cnbootstrap的例子,我整个人都不好了。/base-css.html简直就是愤青……这种人我看像轮子多过像愤青……
11楼:唐阳 来自
感觉还不错
12楼:liubaoxiong
关注,希望能坚持下去。
13楼:kenzr 来自
angular 群的广州 ken 发来贺电
14楼:北落
avalonjs跟jquery就是完全的两种实现思想,拿两者来对比的都是臭流氓。
22:09 (非会员)
引用来自“岭南才子”的评论这类只能在内网使用,跟angular一样,太重了。第一次打开页面下载几百K的身躯。不如jquery轻巧与速度。你懂个屁,不一样的东西
16楼:lost_o0
引用来自“岭南才子”的评论这类只能在内网使用,跟angular一样,太重了。第一次打开页面下载几百K的身躯。不如jquery轻巧与速度。和jquery完全两个东西
17楼:许雷神
从司徒正美处得知,想试试
18楼:onlinelive
耐心看了,试了下,准备在项目用一下。真心好用。
19楼:sikele
引用来自“岭南才子”的评论这类只能在内网使用,跟angular一样,太重了。第一次打开页面下载几百K的身躯。不如jquery轻巧与速度。请你下载一次再说几百k行么?而且和jquery没法比较不是同一种东西。
20楼:雪之舞
真心不喜欢这种在html上加各种自定义属性的东东
与内容无关的评论将被删除,严重者禁用帐号
本周热点资讯
本站最新资讯走进AngularJs(一)angular基本概念的认识与实战 - 吕大豹 - 推酷
走进AngularJs(一)angular基本概念的认识与实战 - 吕大豹
前端技术的发展是如此之快,各种优秀技术、优秀框架的出现简直让人目不暇接,作为一名业界新秀,紧跟时代潮流,学习掌握新知识自然是不敢怠慢。当听到AngularJs这个名字并知道是google在维护它时,便一直在关注,看到其在国外已经十分火热,可是国内的使用情况却有不小的差距,参考文献/网络文章也很匮乏。朝思暮想良久,决定深入学习angular,并写系列博客,一方面作为自己学习路程上的记录,另一方面也给有兴趣的同学一些参考。
首先我自己是一名学习者,会以学习者的角度来整理我的行文思路,故该系列博客也不能叫做教程,只能是些探索,有理解或是技术上的错误还请大家指出。其次我特别喜欢编写小例子来把一件事情说明白,故在文中会尽可能多的用示例加代码讲解,我相信这会是一钟比较好的方式。最后,我深知在现有条件下对于angular的学习会困难重重,不过我更相信坚持的力量,所以谨以此文作为日后学习的动力,让我们一起来走进angular的世界吧~
二、AngularJs是什么
这个定义一定要定准了,AngularJs(后面就简称ng了)是一个用于设计动态web应用的结构框架。首先,它是一个框架,不是类库,是像backbone一样提供一整套方案用于设计web应用。它不仅仅是一个javascript框架,因为它的核心其实是对HTML标签的增强,有图有真相,请看官网描述:
何为HTML标签增强?其实就是使你能够用标签完成一部分页面逻辑,具体方式就是通过自定义标签、自定义属性等,这些HTML原生没有的标签/属性在ng中有一个名字:指令(directive)。后面会详细介绍。那么,什么又是动态web应用呢?与传统web系统相区别,web应用能为用户提供丰富的操作,能够随用户操作不断更新视图而不进行url跳转。ng官方也声明它更适用于开发CRUD应用,即数据操作比较多的应用,而非是游戏或图像处理类应用。
为了实现这些,ng引入了一些非常棒的特性,包括模板机制、数据绑定、模块、指令、依赖注入、路由。通过数据与模板的绑定,能够让我们摆脱繁琐的DOM操作,而将注意力集中在业务逻辑上。这些我将在以后的学习中一一研究。
另外一个疑问,ng是MVC框架吗?还是MVVM框架?官网有提到ng的设计采用了MVC的基本思想,而又不完全是MVC,因为在书写代码时我们确实是在用ng-controller这个指令(起码从名字上看,是MVC吧),但这个controller处理的业务基本上都是与view进行交互,这么看来又很接近MVVM。让我们把目光移到官网那个非醒目的title上:“AngularJS — Superheroic JavaScript MVW Framework”。
好吧,MVW。W—whatever。随便是MV什么好了,所以也有人写为了MV*。其实纠结这个也真没必要,等今后对整个框架熟悉了,其中结构自然了然于心。
三、开始运行angular
有了一个大概的朦胧的了解就够了,我相信很多概念在使用的过程中会慢慢清晰。我迫不及待的想要让angular运行起来了。动手~
首先从官网
下载angular.js,引入你的页面中,然后我们使用最简单的手工启动方式,直接调用bootstrap方法。所有的代码如下:
&!DOCTYPE html&
&meta charset=&utf-8& /&
&title&运行ng&/title&
&script type=&text/javascript& src=&../angular.js&&&/script&
1+1={{1+1}}
angular.bootstrap(document,[]);
只有一行代码。调用bootstrap方法传入作用域和初始化的模块数组(此处为空)。是不是很简单。你很快会看到一处比较特别的,就是这里:
1+1={{1+1}}
如果你使用过其他模板库,应该对这种写法不陌生了,{{}}双大括号,这是ng的模板中用于书写表达式的标记,ng成功运行起来后,{{}}内的表达式会生效,即页面会显示如下:
为了不让你把ng看的这么简单,我必须告诉你一般是不这么启动的,来看稍微修改以后的代码:
&!DOCTYPE html&
&html ng-app=&MyApp&&
&meta charset=&utf-8& /&
&title&运行ng&/title&
&script type=&text/javascript& src=&../angular.js&&&/script&
1+1={{1+1}}
&script type=&text/javascript& charset=&utf-8&&
var app = angular.module('MyApp', [], function(){console.log('started')});
在&html&标签上多了一个属性ng-app=”MyApp”,它的作用就是用来指定ng的作用域是在&html&标签以内部分。在js中,我们调用angular对象的module方法来声明一个模块,模块的名字和ng-app的值对应。关于如何声明、使用模块我们在后面会讲。现在我们只要明白用这种方式可以优雅的让ng运行起来就可以了。
四、模板与数据的绑定
首先需要明确一下模板的概念。在我还不知道有模板这个东西的时候,曾经用js拼接出很长的HTML字符串,然后append到页面中,这种方式想想真是又土又笨。后来又看到可以把HTML代码包裹在一个&script&标签中当作模板,然后按需要取来使用。在ng中,模板十分简单,它就是我们页面上的HTML代码,不需要附加任何额外的东西。在模板中可以使用各种指令来增强它的功能,这些指令可以让你把模板和数据巧妙的绑定起来。
绑定这个东西可是ng中的大功臣了。在我们使用jQuery的时候,代码中会大量充斥类似这样的语句:var v = $(‘#id’).val();$(‘#id’).html(str);即频繁的DOM操作(读取和写入),其实我们的最终目的并不是要操作DOM,而是要实现业务逻辑。ng的绑定将让你摆脱DOM操作,只要模板与数据通过声明进行了绑定,两者将随时保持同步,最新的数据会实时显示在页面中,页面中用户修改的数据也会实时被记录在数据模型中。
我构思了一个小例子,本篇文章的示例将围绕这个小例子来进行。我猜你已经厌倦了登录模块或者是购物车示例,我们来点新颖的。我已化身为一名教师,我要用一个web应用来为学生出一份在线试题。首先从一道题开始吧~
&!DOCTYPE html&
&html ng-app=&MyApp&&
&meta charset=&utf-8& /&
&title&模板数据绑定&/title&
&script type=&text/javascript& src=&../angular.js&&&/script&
&div ng-controller=&testC&&
&h1&{{newtitle}}&/h1&
题目:&input type=&text& ng-model=&name& /&&br /&
分数:&input type=&text& ng-model=&fraction& /&&br /&
&h1&{{previewtitle}}&/h1&
&b&{{name}}&/b&({{fraction}}分)
&script type=&text/javascript& charset=&utf-8&&
var app = angular.module('MyApp', [], function(){console.log('started')});
var testC = function($scope){
$scope.newtitle = '新建试题';
$scope.previewtitle = '预览试题';
$scope.name = $scope.fraction = '';
页面上有分别表示题目和分数的两个输入框,下面有一个实时预览区域,用来展示题目的最终输出效果。ng-controller=”textC”用来声明一个需要和数据进行绑定的模板区域,它的作用域就是这个div之内的东西,并起名为textC,js代码中定义了一个名为textC的函数与它对应,我们将在这个函数内完成绑定。函数传入一个参数$scope,表示这个作用范围。我们分别为作用范围内的newtitle、previewtitle、name、fraction四个变量赋值。此时&h1&标签内的{{}}便能得到相应的值了。
通过{{}}只能完成数据向模板的单向绑定。要想进行双向绑定,我们需要用到ng-modle这个指令,我们使用它分别为题目和分数进行了双向绑定,这样当输入框内的值发生变化时,函数中的变量也会跟随变化,它的变化会实时反馈在下方的预览区域中,因为预览区域中也有一个name和fraction的绑定。
试试在下面的输入框中进行编辑吧~
我们并未进行任何DOM操作,框架自动完成了DOM的取值和赋值。在后面我将继续完善这个例子,并引入更多的新概念。
五、模板中的一些控制方式
我们在使用其他模板库时,一般都会有模板的循环输出、分支输出、逻辑判断等类似的控制。ng模板中都可以进行哪些控制呢?来一块探索之。
&&& 1.循环输出
继续上面的例子。试题光有题目和分数还不够,我想要出一道选择题,可以自己添加若干选项并编辑选项内容,代码该怎么写呢?先上代码:
&div ng-controller=&testC&&
&h1&{{question.newtitle}}&/h1&
题目:&input type=&text& ng-model=&question.name& /&&br /&
分数:&input type=&text& number ng-model=&question.fraction& /&&br /&
选项:&button ng-click=&addOption()&&增加选项&/button&&br /&
&li ng-repeat=&o in question.options&&
&b&{{$index+1}}.&/b&
&input type=&text& ng-model=&o.content& value=&o.content& /&
&a href=&javascript:void(0);& ng-click=&delOption($index)&&删除&/a&
&h1&{{question.previewtitle}}&/h1&
&b&{{question.name}}&/b&({{question.fraction}}分)
&li ng-repeat=&o in question.options&&
&b&{{$index+1}}.&/b&
&input type=&radio& name=&optcheck& /&
{{o.content}}
var app = angular.module('MyApp', [], function(){console.log('started')});
var questionModel = {
newtitle : '新建试题',
previewtitle : '预览试题',
name : '',
fraction : '',
options : []
app.controller('testC',function($scope){
$scope.question = questionM
$scope.addOption = function(){
var o = {content:''};
$scope.question.options.push(o);
$scope.delOption = function(index){
$scope.question.options.splice(index,1);
请注意我的js代码有了一点变化,在数据绑定时没有直接写成字符串,而是将所有的数据写成了一个questionModel对象,这只是一个普遍的js对象,这样能够使我们的数据看起来像是“model”的样子,毕竟我们是MV*嘛。那么在模板中,我们使用name的地方也改成question.name,其他的值也同理。另外在controller部分,我没有用var textC = function(){}这样的写法,而是改成了app.controller(‘textC’,function(){}),这样明确指定了这个controller属于MyApp这个模块,我们的MV*代码看起来更专业、更一体了。
在HTML部分我分别在新建区域和预览区域添加了一个列表,用来放置各选项。并添加了一个“增加选项”按钮。在&li&标签上使用了ng-repeat指令来进行循环输出,&li&标签将会根据$scopt中的options数组长度被复制多份。在循环范围内,可以使用$index获得当前循环的索引,可以认为这是一个公共变量,直接使用。同时,循环输出的每个&input&元素也使用ng-model与选项的内容进行了双向绑定。另外还输出一个删除链接,点击的时候调用$scope中的delOption方法。
这样绑定好之后,模版中的列表与数据模型中的options数组便保持了同步,我们在页面上点击增加选项,数组中便会增加一个元素,数组中的每个元素也会实时反馈在模板中。所以在js代码中,我们只须操作options数组就够了,压根不需要在页面上append或removed节点。
你可以在下面点击增加选项和删除试试~
2.单个节点的控制
在上面的例子中,你是不是发现了,我在处理按钮的点击时,使用了叫做ng-click的指令,为什么不直接用onclick呢?是因为ng根据自己的需要进行了封装。我们把addOption这个函数定义在了controller范围之内,用我们常规的onclick已经无法访问到。换言之,我们页面上的作用域,ng已经帮我们都规划好了,我们只需按照它提供的方式来使用就够了。
通过onclick我们可以联想到,HTML节点还有好多其他属性,如class、style、href、checked、disabled等等,ng对这些都一一进行了封装,更厉害的是,除此之外ng还额外提供了许多更加详细的控制节点的指令。这些指令我以后会详细研究,在这里,我们先拿个其中一个应用到我们的例子中,看看效果先。
我马上变回老师身份,哗~
我新建试题的时候,不要局限于单选题,我想要在单选题和多选题之间能够切换,同时下方的预览区域内,选择框也进行单选框和多选框的切换。上代码:
&div ng-controller=&testC&&
&h1&{{question.newtitle}}&/h1&
题目:&input type=&text& ng-model=&question.name& /&&br /&
分数:&input type=&text& ng-model=&question.fraction& /&&br /&
类型:&select ng-model=&question.type&&&option value=&1& selected&单选&/option&&option value=&2&&多选&/option&&/select&&br /&
选项:&button ng-click=&addOption()&&增加选项&/button&&br /&
&li ng-repeat=&o in question.options&&
&b&{{$index+1}}.&/b&
&input type=&text& ng-model=&o.content& value=&o.content& /&
&a href=&javascript:void(0);& ng-click=&delOption($index)&&删除&/a&
&div preview-panel&
&h1&{{question.previewtitle}}&/h1&
&b&{{question.name}}&/b&({{question.fraction}}分)
&li ng-repeat=&o in question.options&&
&b&{{$index+1}}.&/b&
&input type=&radio& name=&optcheck& ng-show=&question.type==1& /&
&input type=&checkbox& ng-show=&question.type==2& /&
{{o.content}}
Js代码中,我只是在questionModel中新增了一项type:1,表示题的类型,1为单选,2为多选。并给默认值为1.
var questionModel = {
newtitle : '新建试题',
previewtitle : '预览试题',
name : '',
fraction : '',
type : '1',
options : []
在HTML中,我新增了一个下拉框,并与question.type建立双向绑定。需要关注的是下面的预览区域。我又添加了一个checkbox控件来为多选题提供选择框。显然,radio与checkbox不能同时存在,所以我用ng-show这个指令来控制它们的显隐,ng-show接收boolean类型的值以及计算结果为boolean类型的表达式。请注意,ng-show以及其他所有指令的值不是简单的字符串(尽管看上去是那样),而是字符串表达式,拥有计算能力,我现在的理解是它将来会在框架的某个地方放进eval()或是类似的函数执行。{{}}里的内容也是一样。
所以在这里我给radio的ng-show赋值为question.type==1,checkbox的ng-show赋值为question.type==2。当试题是单选题时,radio的ng-show便能得到值true,从而显示出来。在下面看一下效果:
其他的节点控制指令也可以类似这样使用,思想就是根据你的业务逻辑,赋予它们一定的表达式。其他的控制还有事件绑定、表单控件等等,篇幅的限制在这里就不讲了,以后专门开一篇介绍。
3.过滤器(filter)
所谓过滤器是指对输出的内容进行格式化,如格式化为美元、日期等。框架自己提供一些过滤器,如排序、字符串内容筛选。我们也可以自定义过滤器。
过滤器在{{}}中使用,表达式后用|隔开使用。拿日期过滤器举例,方式如下:
$scope.nowTime = new Date().valueOf();
{{nowTime | date : 'yyyy-MM-dd HH:mm:ss'}}
便会输出格式化的日期。是不是很方便呢。
接上一步的例子,我想要在预览区域中的题目前面显示题型,像[单选题]这样。我们的questionModel中,type的值是1和2,所以我们要做的就是通过过滤器,把1和2显示为单选题和多选题。Go~
在js中定义一个名为typeFilter的过滤器:
app.filter('typeFilter',function(){
var f = function(input){
return input == '1' ? '单选题' : '多选题';
filter函数如何使用以及执行细节不是本篇的讨论内容,所以现在只要明白这样可以定义一个过滤器就可以了。结构姑且认为是固定写法,代码不难看懂。
定义后这个filter后我们便可以在模板中使用了:
&b&[{{question.type | typeFilter}}]{{question.name}}&/b&({{question.fraction}}分)
在题目的前面显示题型,并使用typeFilter,效果如下:
单调的“1”已经华丽转身变为了“单选题”。这只是一个简单的过滤器。你可以发挥想象力编写更强大的过滤器。
六、指令(directive)
前面已经提到很多次指令了,现在来正式介绍一下它。指令是ng为HTML补充的语法扩展,用于增强HTML的表现力。像我们之前使用的ng-controller、ng-model等都属于指令。你也可以自定义指令。ng内部包含了一个强大的DOM解析引擎,所以这些新的标签或是标签属性可以像使用原生HTML那样很好的工作。
听起来很牛的样子,那我们来试试自己定义一个指令吧。注意,我要变形了~
我是教师,在新建试题输入分数的时候应该只能输入数字才对,输入其他内容是不合法的,而且我希望这个分数是1~10之间的数字。能否只在输入框上加一个属性就完成这个验证呢?就像使用HTML5新增的required一样。
我们定义一个叫做fractionNum的指令如下:
app.directive('fractionNum',function(){
link : function(scope, elements, attrs, controller){
elements[0].onkeyup = function(){
if(isNaN(this.value) || this.value&1 || this.value&10){
this.style.borderColor = 'red';
this.style.borderColor = '';
哇,代码好多层级呀,不要慌张,稳住阵脚!其实最后就是返回了带有link字段的对象,link的值是一个函数,用来定义指令的行为。从传入的参数中可以获取到当前元素,我们便可以拿当前元素开刀了。我在此处监听当前元素的keyup事件,获取元素的值,如果不是1~10之间的数字,则把输入框的边框颜色变为红色。这下这个指令就可以工作了。
至于传入的四个参数到底都有什么玄机,我暂时还未研究,也不是本篇的重点,本篇只是做一个概览,先把ng拉出来溜溜的意思。现在姑且可以认为,一个指令的固定写法大概就是这个结构。
定义好的指令就可以在模板中使用了,使用方法如下:
分数:&input type=&text& ng-model=&question.fraction& fraction-num /&&br /&
把它加在了分数输入框上,此处要特别小心一个写法,我定义的时候名字是fractionNum,用在模板中需要写成fraction-num,就是因为名字中含有大写字母的原因,感觉上跟使用css属性名称有点像。如果定义的时候没有大写字母,就不必担心这一点了。
看效果,现在你可以去下面蹂躏那个分数输入框去了~
七、依赖注入
通过依赖注入,ng想要推崇一种声明式的开发方式,即当我们需要使用某一模块或服务时,不需要关心此模块内部如何实现,只需声明一下就可以使用了。在多处使用只需进行多次声明,大大提高可复用性。
比如我们的controller,在定义的时候用到一个$scope参数。
app.controller('testC',function($scope){});
如果我们在此处还需操作其他的东西,比如与浏览器地址栏进行交互。我们只需再多添一个参数$location进去:
app.controller('testC',function($scope,$location){});
这样便可以通过$location来与地址栏进行交互了,我们仅仅是声明了一下,所需的其他代码,框架已经帮我们注入了。我们很明显的感觉到了这个函数已经不是常规意义上的javascript函数了,在常规的函数中,把形参换一个名字照样可以运行,但在此处若是把$scope换成别的名字,程序便不能运行了。因为这是已经定义好的服务名称。
这便是依赖注入机制。顺理成章的推断,我们可以自己定义模块和服务,然后在需要的地方进行声明,由框架来替我们注入。
对,我的小例子呢?我现在要想点需求来把依赖注入试验一下。我觉得试题全是文字太单调了,我希望题目中能含有图片/音视频,或者选项中可以含有图片/音视频。并且,我要更灵活一点,我要为试题提供若干套模板来选择,选择不同的模板可以新建不同样式的题,比如模板一为纯文字试题、模板二为题目中带图片/音视频的试题、模板三为选项中带图片/音视频的试题,等等。注意此处所说的模板跟ng的模板不是一个概念,是我自己试题的模板,不要混淆。这些模板应该是与试题相分离的,以后可以为其他题型例如填空题啊简答题啊同样使用。所以试题模板这个东西就需要做成服务了。
不知道我表达清楚了没有,确实有点绕。来看下我们如何定义一个服务:
app.factory('tpls',function(){
return ['tpl1','tpl2','tpl3','tpl4'];
看上去相当简单,是因为我在这里仅仅是直接返回一个数组。在实际应用中,这里应该是需要向服务器发起一个请求,来获取到这些模板们。服务的定义方式有好几种,包括使用provider方法、使用factory方法,使用service方法。它们之间的区别暂且不关心。我们现在只要能创建一个服务出来就可以了。我使用了factory方法。一个需要注意的地方是,框架提供的服务名字都是由$开头的,所以我们自己定义的最好不要用$开头,防止发生命名冲突。
定义好一个服务后,我们就可以在控制器中声明使用了,如下:
app.controller('testC',function($scope,tpls){
$scope.question = questionM
$scope.nowTime = new Date().valueOf();
$scope.templates = //赋值到$scope中
$scope.addOption = function(){
var o = {content:''};
$scope.question.options.push(o);
$scope.delOption = function(index){
$scope.question.options.splice(index,1);
此时,若在模板中书写如下代码,我们便可以获取到服务tpls所提供的数据了:
模板:&a href=&javascript:void(0);& ng-repeat=&t in templates&&{{t}}&&&/a&&br /&
随着知识点的一点点增加,我的这个小例子也越来越丰满了,来看看完整版吧:
{{question.newtitle}}
模板:{{t}}
{{$index+1}}.
{{question.previewtitle}}
[{{question.type | typeFilter}}]{{question.name}}
({{question.fraction}}分)
{{$index+1}}.
{{o.content}}
已发表评论数()
&&登&&&陆&&
已收藏到推刊!
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见}

我要回帖

更多关于 mvvm模式 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信