avalon2学习教程09循环操作
avalon2的循环指令的用法完全改变了。avalon最早期从knockout那样抄来ms-each,ms-with,分别用于数组循环与对象循环。它们都是针对元素内容进行循环。后来又从angular那里抄来了ms-repeat, 这是循环元素内部的。
到avalon2,这三个指令合并成一个ms-for指令 ,用法与angular更相似,但没有$index, $last, $first, $middle.
如果想得到数组元素或对象的键值,在in关键字前指定一个新变量
<div ms-for="el in @arrayOrObject">{{el}}</div>
如果要指定数组索引值或对象的键名,那么需要加一个小括号
<div ms-for="(index,el) in @arrayOrObject">{{el}}</div>
我们可以用limitBy, filterBy, orderBy, selectBy过滤器生成新的循环体
<div ms-for="(index,el) in @arrayOrObject | filterBy('name')">{{el}}</div>
如果用limitBy过滤器,那么数组的长度或对象的大小会变小,那我们现在就不
知道现在的长度,因此我们需要另一个变量引用新对象新数组
<div ms-for="(index,el) in @arrayOrObject as newArray| filterBy('name')">{{el}}::{{newArray.length}}</div>
如果想实现之前的$fist, $last效果,那就需要用到js指令
<div ms-for="(index,el) in @arrayOrObject as newArray| filterBy('name')">
<!--ms-js:var $first = $index === 0 -->
<!--ms-js:var $last = $index === new Array -2 -->
</div>
这是我们第一次见到以注释节点存在的指令了。实质上,ms-if的值为false,创建的注释节点也算是一种注释指令。
而avalon2是没有像angular那样的ng-repeat-start, ng-repeat-end这样圈 定某个范围的辅助指令。换言之,不能像ms-repeat那样循环多个元素。
这时我们需要了解一下其内部机制。这个以元素属性存在的ms-for指令,会翻译成以注释节点存在的ms-for指令。
<div class='panel' ms-for="($index, el) in @array">{{el}}::{{$index}}</div>
等价于
<!--ms-for:($index,el) in @array-->
<div class='panel'>{{el}}::{{$index}}</div>
<!--ms-for-end:-->
这有点复杂,但可以解决我们循环多个元素的问题
<!--ms-for:($index,el) in @array-->
<td>{{el.td1}}</td>
<td>{{el.td2}}</td>
<!--ms-for-end:-->
注意,avalon2的监控数组已经移除size()方法,由于内部使用了虚拟DOM,你直接使用@array.length就能得知道当前长度了。
avalon2也没有angular的track by机制,或像React那样强制使用key.这种为优化排序性能的方法,avalon内部帮你搞定,就不需要你多写什么了。
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script src="./dist/avalon.js" ></script>
<script>
var vm = avalon.define({
$id: "test",
array: ["aaa","bbb","ccc"]
})
setTimeout(function(){
vm.array = ['ccc','dd1','dd2','dd3']
},3000)
</script>
</head>
<body ms-controller="test">
<ul>
<li ms-for="($index, el) in @array">{{el}} --- {{$index}}</li>
</ul>
</body>
</html>
我们再来看一下如何循环二维数组
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script src="./dist/avalon.js" ></script>
<script>
var vm = avalon.define({
$id: "test",
array: [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
})
setTimeout(function(){
vm.array.set(0, [13,14,15,16])
},3000)
</script>
</head>
<body ms-controller="test">
<table border="1">
<tr ms-for="($index, el) in @array">
<td ms-for="elem in el">{{elem}} 它位于第<b style="color:orchid">{{$index}}</b>行</td>
</tr>
</table>
</body>
</html>
图上的这些注释节点,你用过angular也会发现类似的东西,这是方便框架对这些元素进行排序增删操作设计的。大家不要手动移除它们。
我们再看一个经典的例子,如何通过操作数组为列表添加或移除某一项!另,大家也可以对照这里看看avalon1是怎么实现的,你就明白avalon2在这方面的巨大优势与便利。
<!DOCTYPE HTML>
<html>
<head>
<title>ms-repeat</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script src="./dist/avalon.js" ></script>
<script>
var definition = {
$id: 'test',
array: ['1', '2', '3', '4'],
removeAt: function (e) {
var elem = e.target
if (isFinite(elem.value)) {//this为input元素
var a = ~~elem.value
this.array.removeAt(a)
elem.value = ''
}
}
}
'push,unshift,remove,ensure'.replace(avalon.rword, function (method) {
definition[method] = function (e) {
//avalon2中,所有通过ms-on-* 及其变体绑定的事件,其this都是指向vm,
//而元素本身则通过e.targeta得到
var elem = e.target
if (elem.value) {
this.array[method](elem.value)
elem.value = ''
}
}
})
'pop,shift,sort,reverse'.replace(avalon.rword, function (method) {
definition[method] = function (e) {
this.array[method]()
}
})
avalon.define(definition)
</script>
</head>
<body ms-controller="test">
<p>监控数组拥有以下方法,我们可以操作它们就能同步对应的区域</p>
<blockquote>
push, shift, unshift, pop, slice, splice, remove, removeAt, removeAll, clear,
ensure, pushArray, sort, reverse, set
</blockquote>
<ul>
<li ms-for="($index,el) in @array">数组的第{{$index+1}}个元素为{{el}}</li>
</ul>
<p>对数组进行push操作,并回车<input ms-keypress="@push | enter"></p>
<p>对数组进行unshift操作,并回车<input ms-keypress="@unshift | enter"></p>
<p>对数组进行ensure操作,并回车<input ms-keypress="@ensure | enter"><br/>
(只有数组不存在此元素才push进去)</p>
<p>对数组进行remove操作,并回车<input ms-keypress="@remove | enter"></p>
<p>对数组进行removeAt操作,并回车<input ms-keypress="@removeAt | enter"></p>
<p><button type='button' ms-click="@sort">对数组进行sort操作</button></p>
<p><button type='button' ms-click="@reverse">对数组进行reverse操作</button></p>
<p><button type='button' ms-click="@shift">对数组进行shift操作</button></p>
<p><button type='button' ms-click="@pop">对数组进行pop操作</button></p>
<p>当前数组的长度为<span style="color:red">{{@array.length}}</span>。</p>
</body>
</html>
最后我们来一个表格的实用例子。之前avalon的大表格渲染时存在性能问题,现在大大得到改进了。
<!DOCTYPE html>
<html>
<head>
<title>TODO supply a title</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="./dist/avalon.js"></script>
<script>
var vm = avalon.define({
$id: 'for3',
header: ['name','age','sex'],
list: []
})
var sexMap = {
true: "男",
false: "女"
}
function genData(n){
var ret = []
for(var i =0 ; i< n; i++){
ret.push({
name: Math.random(),
age: 3+ Math.ceil((Math.random() *30)),
sex: sexMap[1-Math.random() > 0.5],
desc: Math.random()
})
}
return ret
}
setInterval(function(){
var t1 = Date.now();
vm.list = genData(100)
console.log('total ' + (Date.now() - t1) + ' ms');
}, 70);
</script>
</head>
<body>
<div ms-controller='for3' >
<table border="1">
<tr><th ms-for='el in @header'>{{el}}</th></tr>
<tr ms-for='tr in @list'>
<td ms-for='td in tr | selectBy(["name","age","sex"])' ms-attr="{align:td === 'age' ?'left':'right'}">{{td}}</td>
</tr>
</table>
</div>
</body>
</html>
avalon2学习教程09循环操作的更多相关文章
- avalon2学习教程06样式操作
avalon2的ms-css的变革思路与ms-attr一样,将多个操作合并成到一个对象里面处理,因此没有ms-css-name="value",只有ms-css="Obj ...
- avalon2学习教程15指令总结
avalon的指令在上一节已经全部介绍完毕,当然有的语焉不详,如ms-js.本节主要总结我对这方面的思考与探索. MVVM的成功很大一语分是来自于其指令,或叫绑定.让操作视图的功能交由形形式式的指令来 ...
- avalon2学习教程14动画使用
avalon2实际上没有实现完整的动画模块,它只是对现有的CSS3动画或jquery animate再包装一层. 我们先说如何用CSS3为avalon实现动画效果.首先要使用avalon.effect ...
- avalon2学习教程13组件使用
avalon2最引以为豪的东西是,终于有一套强大的类Web Component的组件系统.这个组件系统媲美于React的JSX,并且能更好地控制子组件的传参. avalon自诞生以来,就一直探索如何优 ...
- avalon2学习教程12数据验证
avalon2砍掉了不少功能(如ms-include,ms-data),腾出空间加了其他更有用的功能.数据验证就是其中之一.现在avalon2内置的验证指令是参考之前的oniui验证框架与jquery ...
- avalon2学习教程08插入移除操作
本节介绍的ms-if指令与ms-visible很相似,都是让某元素"看不见",不同的是ms-visible是通过CSS实现,ms-if是通过移除插入节点实现. ms-if的用法与1 ...
- avalon2学习教程05属性操作
avalon2与avalon1的属性操作虽然都是使用ms-attr,但用法完全不一样. avalon1是这样操作属性的 其语法为 ms-attr-valueName="vmProp" ...
- avalon2学习教程 03数据填充
数据填充是一个模版最基础的功能,直接从JSON(vm)取出数据,放到适当的位置上.在静态模板中,不区分文本与HTML,只看你的字符串是否有< >来决定生成文本节点与元素节点.但MVVM中, ...
- avalon2学习教程02之vm
avalon2的vm是一个非常重要的东西,其设计原型最初脱胎于knockout.js,但到avalon1.6中,终于寻得自己的方案,更精简,更易用,更魔幻. vm是一种特殊的数据结构,看起来像普通对象 ...
随机推荐
- Animations功能(区别于Transitions)
CSS3实现动画: 1 Transitions:定义元素的某个属性从一个属性值平滑过渡到另一个属性值. Transitions属性的使用方法如下所示: transition: property | ...
- 引用计数gc机制使用不当导致内存泄漏
上一篇文章找同事review了一下,收到的反馈是铺垫太长了,我尽量直入正题,哈哈 最近dbd压测时发现内存泄漏,其实这个问题去年已经暴露了,参见这篇博客[压测周].当时排查不够仔细,在此检讨下.关于d ...
- CentOS 6.5 安装CodeBlocks
CentOS 6.5 安装CodeBlocks 经历了无数痛苦的折磨,Linux上的库依赖真是能把人逼疯,终于在Google上找到了办法,勉强将CodeBlocks安装成功. 1.为了避免最新版本的C ...
- ajax上传图片到服务器
通过Ajax方式上传文件,使用FormData进行Ajax请求.上传文件或图片时,要求的格式为enctype ="multipart/form-data"(以二进制格式上传),在使 ...
- while do while 穷举和迭代
新内容1:while循环 格式: while() { } 初始状态要在循环外提前规定 状态改变要写在花括号里面 括号内是循环条件 for循环与while循环的对比: 穷举: 迭代:
- VoxelGrid体素滤波器对点云进行下采样
使用体素化网格方法实现下采样,即减少点的数量,减少点云数据,并同时保持点云的形状特征,在提高配准.曲面重建.形状识别等算法速度中非常实用. PCL实现的VoxelGrid类通过输入的点云数据创建一个三 ...
- bash的操作环境[转]
Bash Shell 的操作环境: 是否记得我们登陆主机的时候,屏幕上头会有一些说明文字,告知我们的 Linux 版本啊什么的, 还有,登陆的时候我们还可以给予用户一些信息或者欢迎文字呢. ...
- oracle 查询数据库表空间大小和剩余空间
dba_data_files:数据库数据文件信息表.可以统计表空间大小(总空间大小). dba_free_space:可以统计剩余表空间大小. 增加表空间即向表空间增加数据文件,表空间大小就是数据文件 ...
- ASP.NET获取IP的6种方法 ( 转)
原文转自:http://www.cnblogs.com/blodfox777/archive/2008/07/21/1247447.html 服务端: //方法一 HttpContext.Curren ...
- Android 后端 Bmob的使用
网上发现一个很不错的东西Bmob,推荐给大家使用. Bmob可以开发一个云存储的移动应用软件,给应用软件快速添加一个安全灵活的后台管理系统,方便浏览终端保存的各种信息. 如果觉得创建服务器程序比较麻烦 ...