新手刚学自家车练MS求指教。。。。。刚练的一个MS。...

前端神器avalonJS入门(一)
我的图书馆
前端神器avalonJS入门(一)
avalonJS是司徒正美开发和维护的前端mvvm框架,可以轻松实现数据的隔离和双向绑定,相比angularJS等前端框架它有如下优势:
1.压缩后仅有60多kb,而angular的min版是2MB左右(无视其gzip版);
2.兼容IE6+,符合天朝市场需求;
3.效率更高,跑起来比angular和knockout都要更快,在移动端上该优势会更大(avalon有移动端专版的avalon.modern.js)。关于其性能更详细的介绍可以看
4.涵盖了angular的大部分功能,且实现方式更为便捷、上手更容易;
5.有配套的UI库(当然这个按需选择即可),由司徒正美及其“去哪儿”团队维护,有相关的中文文档(下方会提到),除了在github提交issue,你也可以加入正美的Q群 来交流问题或提交bug。
(这位兄台,谷歌送温暖,开门查水表)
然而avalon也有自己的劣势----知名度较低。不过毕竟国产的东西没经BAT推广,要像seaJS那样驰名中外倒是不容易。
相关中文文档
正美其实私下写了不少avalon的官方api和教程,大家可以访问如下地址:
(下载最新的avalon以及实例(examples文件夹里),通过实例来掌握某些功能的实现是很好的学习途径)
(比较快捷的入门课程,只用了几篇文章来介绍了最常用的一些功能)
API文章(正美的博文,篇幅较大,涵盖知识点很多,可以当作API来查阅,只是正美的博客排版真的。。。看起来略吃力),也可以在
查看更规范的API。
(强烈推荐,用了20多篇文章较详细地、渐进地介绍avalon,必读的就是啦)
本系列初衷
虽然正美已经细心编写了不少中文文档,不过有的文章技术门槛有点高,不太适合初学者,另外作为avalon的用户,以用户的角度来较详细地介绍avalon或许会更合适些。
本系列相比正美的教程,会更侧重于“怎么用”,而非其机制或原理的介绍。
另外也希望本系列能为推广avalon出一份绵薄之力,希望能让更多的前端爱好者开始接触avalon,并喜欢上这个前端利器。
本系列技术需求
本系列除了avalonJS之外,还会搭配requireJS做辅助,特别是后面我们会使用avalon的路由系统,来做一个单页面站点(放到移动端就是SPA了),需要requireJS及其插件来按需加载脚本和样式文件,故建议查阅本系列的朋友要多多少少会一点requireJS的知识。
个人还是觉得avalon搭配requireJS的话,在前端可谓hold住全场了(咱忽略node及其框架...)~
我们可以在
获取最新版本的avalonJS,然后将其引入页面中(本章先不考虑搭配requireJS,仅仅先玩一玩、介绍下):
&!DOCTYPE html&
&head lang="en"&
&meta charset="UTF-8"&
&title&初玩阿瓦隆&/title&
&script type="text/javascript" src="avalon.js"&&/script&
&div&&/div&
接着,类似于ng的“ng-controller”,avalon的控制域属性名叫做“ms-controller”,你可以把它当作一个***器,把它绑定到一个容器后,avalon就能扫描和***这个容器内的所有
(绑定了avalon方法或带有插值表达式的)
我们来给div加上这个***器,并在里面写一个 avalon插值表达式{{ XXX }} :
&div ms-controller="wrap"&{{a}}&/div&
你现在运行它的话,还没有任何效果,因为我们还没有写脚本来让avalon工作起来。我们可以来这么一段简单的脚本:
&div ms-controller="wrap"&{{a}}&/div&
&script type="text/javascript"&
var abc = avalon.define({
//abc是随便起的一个名字,用作该Model的载体
$id: "wrap",
//告诉avalon这个Model是作用于哪个ms-controller的
a: "你好啊"
//定义一个avalon对象属性“a”,其值是“你好啊”
avalon.scan(); //要在最后加这一句,让avalon扫描文档,从而执行起来
在avalon中,我们用 avalon.define({ ...& }) 的形式来定义一个Model实例(其参数可以看做一个avalon数据对象),其中的& $id& 是内置属性,对应所要扫描和监控的控制域名。
我们还在内部定义了一个属性"a",故在对应的控制域 (如这段代码对应的域是绑定ms-controller="wrap"的div标签) 里,我们使用avalon插值表达式{{a}}的话,可以自动绑定其值“你好啊”。
上述代码运行效果如下:
当然,avalon有着更类似ng的写法:
avalon.define("wrap", function(vm) {
但个人觉得没必要,还是下方的写法来的简单(本系列后续的实例也将遵从该写法):
var vm = avalon.define({
下面这段代码可以帮你更好了解avalon的控制域:
&div ms-controller="wrap"&{{a}}&/div&
&div ms-controller="wrap2"&
&span&{{b}}&/span&
&script type="text/javascript"&
var abc = avalon.define({
$id: "wrap",
a: "你好啊"
var def = avalon.define({
$id: "wrap2",
a: "大家好",
b: "哈哈哈"
avalon.scan();
执行效果如下:
两个作用域(ms-controller)之间可以互相访问彼此的数据,还记得我们给avalon.define的前面定义了一个载体么(varXX= avalon.define),利用它就能轻松获取:
&div ms-controller="wrap"&{{a}}&/div&
&div ms-controller="wrap2"&
&span&{{b}}&/span&
&script type="text/javascript"&
var abc = avalon.define({
$id: "wrap",
a: "你好啊"
var def = avalon.define({
$id: "wrap2",
a: "大家好",
//获取第一个Model里的属性值
avalon.scan();
执行效果:
数据和视图同步
上方我们实现了非常简单的数据绑定,将一个avalon对象属性a绑定到DOM元素上。不过avalon更有趣和实用的地方是它实现了数据与视图的同步,说的简单点,我们用脚本修改了a的值,那么DOM上绑定的数据也会跟着改变(当然反过来也是一样的):
&div ms-controller="wrap"&
&span&{{a}}&/span&
&input ms-duplex="a" /&
&script type="text/javascript"&
var abc = avalon.define({
$id: "wrap",
a: "你好啊"
avalon.scan();
注意我们这里增加了一个&&inputms-duplex="a"/& ,其中的 ms-duplex 是avalon的双工绑定属性,它除了负责将VM中对应的值(如本例是a)放到表单元素的value中,还对元素偷偷绑定一些事件,用于***用户的输入从而自动刷新VM。
执行如下:
利用avalon数据-视图同步的特性,我们可以更便捷地、更少代码地实现某些功能。举个例子,我们来实现一个选项卡的功能:
如上图的选项卡你会如何实现呢?可能你会写两个ul来对应下方两个选项卡列表,每个ul里都写上4个li(或者让后端人员通过后端框架来写loop,从而动态生成li),然后你再把第二个ul隐藏了,接着写个方法,让鼠标移到第二个选项卡标题时,第一个ul隐藏,第二个ul显示,对吧。
还有右上角的 “更多XX” 的连接,也可以通过隐藏-显示的方式来实现
你的DOM代码可能是这样的:
&span id="gg"&公告&/span&&span id="bd"&媒体报道&/span&
&a id="more_gg" href="#!/gg"&更多公告&/a&&a id="more_bd" href="#!/bd"&更多报道&/a&
&ul id="gg_list"&
&li&&a href="#!/gg/1" title="公告文章标题1"&公告文章标题1&/a&&/li&
&li&&a href="#!/gg/2" title="公告文章标题2"&公告文章标题2&/a&&/li&
&li&&a href="#!/gg/3" title="公告文章标题3"&公告文章标题3&/a&&/li&
&li&&a href="#!/gg/4" title="公告文章标题4"&公告文章标题4&/a&&/li&
&ul id="bd_list"&
&li&&a href="#!/bd/1" title="媒体报道文章标题1"&媒体报道文章标题1&/a&&/li&
&li&&a href="#!/bd/2" title="媒体报道文章标题2"&媒体报道文章标题2&/a&&/li&
&li&&a href="#!/bd/3" title="媒体报道文章标题3"&媒体报道文章标题3&/a&&/li&
&li&&a href="#!/bd/4" title="媒体报道文章标题4"&媒体报道文章标题4&/a&&/li&
但使用avalon的话,一切都更简单:
&div ms-controller="list"&
&span ms-mouseover="changeUl(gg)"&公告&/span&
&span ms-mouseover="changeUL(bd)"&媒体报道&/span&
&a ms-href="'#!/'+ more_name"&{{more_text}}&/a&
&li ms-repeat="infoList"&
&a ms-href="'#!/'+ more_name + '/' + el.id" ms-title="el.title"&{{el.title}}&/a&
首先它只有一个“更多XX”的&a&标签,而且只有一个&ul&,而且不存在任何后端标签的介入就能实现数据循环绑定。
它的优势在数据越多的时候会越明显(例如每个ul要显示100条li)。
我们来看看avalon的脚本应当怎么写:
&script type="text/javascript"&
var gg=[{"id":"1","title":"公告文章标题1"},{"id":"2","title":"公告文章标题2"},{"id":"3","title":"公告文章标题3"},{"id":"4","title":"公告文章标题4"}];
var bd=[{"id":"1","title":"媒体报道文章标题1"},{"id":"2","title":"媒体报道文章标题2"},{"id":"3","title":"媒体报道文章标题3"},{"id":"4","title":"媒体报道文章标题4"}];
&div ms-controller="list"&
&span ms-mouseover="changeUl(1)"&公告&/span&
&span ms-mouseover="changeUl(0)"&媒体报道&/span&
&a ms-href="'#!/'+ more_name"&{{more_text}}&/a&
&li ms-repeat="infoList"&
&a ms-href="'#!/'+ more_name + '/' + el.id" ms-title="el.title"&{{el.title}}&/a&
&script type="text/javascript"&
var vm = avalon.define({
$id: "list",
more_name: "gg",
more_text: "更多公告",
infoList:gg,
changeUl:function(flag){
//鼠标移过“公告”选项卡头部
vm.more_name = "gg";
vm.more_text = "更多公告";
vm.infoList = vm.
//鼠标移过“媒体报道”选项卡头部
vm.more_name = "bd";
vm.more_text = "更多报道";
vm.infoList = vm.
avalon.scan();
执行效果:
我们来逐步分析下上方的代码。首先看第一段脚本:
&script type="text/javascript"&
var gg=[{"id":"1","title":"公告文章标题1"},{"id":"2","title":"公告文章标题2"},{"id":"3","title":"公告文章标题3"},{"id":"4","title":"公告文章标题4"}];
var bd=[{"id":"1","title":"媒体报道文章标题1"},{"id":"2","title":"媒体报道文章标题2"},{"id":"3","title":"媒体报道文章标题3"},{"id":"4","title":"媒体报道文章标题4"}];
这里的 gg 表示“公告”的列表JSON数据,bd 则是“媒体报道”的列表JSON数据,你可以让后端的朋友直接在此处提供JSON数据过来。我们后续会利用avalon把这些数据绑定到页面视图上。
我们再看DOM结构:
&div ms-controller="list"&
&span ms-mouseover="changeUl(1)"&公告&/span&
&span ms-mouseover="changeUl(0)"&媒体报道&/span&
&a ms-href="'#!/'+ more_name"&{{more_text}}&/a&
&li ms-repeat="infoList"&
&a ms-href="'#!/'+ more_name + '/' + el.id" ms-title="el.title"&{{el.title}}&/a&
&span&中的 ms-mouseover 是avalon的“onmouseover”方法,其值 changeUl(X) 是我们在最后的avalon脚本中定义的一个事件方法,然后比如当鼠标移到“媒体报道”的span上,会触发绑定是 changeUl(0) 事件。
我们再看看&&ams-href="'#!/'+ more_name"&{{more_text}}&/a& &这里的 ms-href 自然也是avalon中的“href”属性,可以植入avalon对象属性(如这里的more_name),也可以加上字符串(如这里的'#!/'),但要用引号括起来,不然会被当作avalon对象属性处理。
接着是最重要的部分:
&li ms-repeat="infoList"&
&a ms-href="'#!/'+ more_name + '/' + el.id" ms-title="el.title"&{{el.title}}&/a&
我们使用了 ms-repeat="XX" 属性来绑定要重复显示的哈希数据,同时会生成一个代理VM对象,该代理对象拥有el,$index, $first, $last, $remove 等属性(点这里查看详细),其中我们用到的 el 表示指向当前的数据元素,从而可以通过 el.id ,el.title 来获取infoList数组对象的具体元素。
最后咱再看看avalon脚本:
&script type="text/javascript"&
var vm = avalon.define({
$id: "list",
more_name: "gg",
more_text: "更多公告",
//获取公告JSON数据
//获取媒体报道JSON数据
infoList:gg,
//infoList缺省值为公告JSON数据
changeUl:function(flag){
//鼠标移过“公告”选项卡头部
vm.more_name = "gg";
vm.more_text = "更多公告";
vm.infoList = vm.
//infoList变为公告JSON数据
//鼠标移过“媒体报道”选项卡头部
vm.more_name = "bd";
vm.more_text = "更多报道";
vm.infoList = vm.
//infoList变为媒体报道JSON数据
avalon.scan();
这里要注意的是我们用了
//获取公告JSON数据
//获取媒体报道JSON数据
来获取和存储“公告/媒体报道”的JSON数据到avalon对象的属性中(左侧的gg和bd是avalon对象属性,右侧的gg和bd是全局变量),这样做的原因是后续的回调事件changeUl(flag)要通过参数来判断和修改vm.infoList的值,而其值应同为avalon对象属性。如果把代码改为这样会出错(刚用avalon的朋友可能就会这样写):
&script type="text/javascript"&
var vm = avalon.define({
$id: "list",
more_name: "gg",
more_text: "更多公告",
infoList:gg,
//infoList缺省值为公告JSON数据
changeUl:function(flag){
//鼠标移过“公告”选项卡头部
vm.more_name = "gg";
vm.more_text = "更多公告";
vm.infoList =
//鼠标移过“媒体报道”选项卡头部
vm.more_name = "bd";
vm.more_text = "更多报道";
vm.infoList =
avalon.scan();
执行效果如下:
是的,鼠标第一次移上去的时候是无误的,但再移到其它选项卡的时候就不按常理出牌了,这是为什么?
我个人认为,在我们第一次获取全局变量之后,avalon就会把该变量变为一个avalon对象,导致该变量的值就这么被改变了,你可以这样来调试:
var vm = avalon.define({
$id: "list",
more_name: "gg",
more_text: "更多公告",
infoList:gg,
changeUl:function(flag){
console.table(gg); //console出“公告”变量的数据信息
vm.more_name = "gg";
vm.more_text = "更多公告";
vm.infoList = vm.
vm.more_name = "bd";
vm.more_text = "更多报道";
vm.infoList = vm.
avalon.scan();
结果(第一次回调事件的gg是正常的,但第二次开始就改变了):
因此我们要记得,若存在外部引入的数据,应用一个avalon对象属性保存起来。
第一篇入门文章就到这里,下一篇我们开始以配合requireJS的形式来使用avalon,共勉~
馆藏&21598
TA的推荐TA的最新馆藏[转]&[转]&[转]&[转]&[转]&[转]&[转]&[转]&[转]&新手蓝白卡组分享
偏快速的牧师卡组_17173炉石传说专区_炉石传说官网合作站点_中国游戏第一门户站
> 新手蓝白卡组分享
偏快速的牧师卡组
新手蓝白卡组分享
偏快速的牧师卡组
因为NAXX开放之后楼主发现很多卡都适合牧师带,这套卡组就是要逆转牧师偷牌狗+防守反击的形象,大声说出来牧师也是可以刚正面的!
卡组详情:低端楼主15级守门员+竞技场送温暖选手一名,天梯打得少,最高只到7,所以没太大说服力,如果喷请轻喷。因为NAXX开放之后楼主发现很多卡都适合牧师带,这套卡组就是要逆转牧师偷牌狗+防守反击的形象,大声说出来牧师也是可以刚正面的!(偶尔偷张调剂一下,无伤大雅)值得一提的是根据楼主浅薄的经验,这套卡组可以有效克制天梯中横行无忌的猎人和动物园术士,至少胜率不会太低,对半开完全没有问题。打土豪的话就要用快攻的思路,手顺也不虚,经常能抢血抢死。众所周知牧师的职业技能在前期没什么好的发挥,以致传统卡组经常出现前几费无事可干的情况,这套卡的思路就是前期高血仆从站场,配合牧师技能能够无伤换怪,拉开卡差。这套卡组里的combo非常的多,送葬者不说了,奥金尼+环,剑圣+环,奥金尼+僵尸,死亡领主+心火,牧师新卡+心火也能形成很好的配合。环的作用非常大,给死亡领主加血好顶赞!嘲讽多,可以有效保护其他怪。打动物园前期下出死亡领主对面会非常难受,配合碧池刷牌换怪,很快能掌握节奏。暗影狂乱有奇效,带多卡手。打猎人的话因为仆从质量高,都是大屁股,而且铺得快,不怕爆炸也不怕冰冻(碧池僵尸都可以撞,副作用小)经常放狗没出来已经残血了。而且牧师也完全不怕被抢血。嘲讽一架很快就可以刷起来。对待其他职业就是铺场,养送葬,养高血怪心火砸,节奏很快。卡组尚有瑕疵,楼主只是提供一个思路,希望大神可以发扬光大。(至于为什么不带麻风侏儒养送葬,楼主的思路是站场,麻风侏儒站不住场还亏卡。而且这套牌是滚雪球养怪,铺怪把对面铺死,并不是抢血,因为奥金尼摸不到的话僵尸就是给对面送血,换怪是第一位的。)
手机看攻略,电脑玩游戏两不误!
加点再也不需要切来切去啦~
【炉石传说】最新消息第一时间推送给你
与相关的文章有:
给力卡组推荐
热门专题推荐
新闻排行榜

参考资料

 

随机推荐