迷你MVVM框架 avalonjs 学习教程4、数据填充
MVVM是前端的究极解决方案,你们可能用过jQuery,但那个写的代码不易维护;你们可以听过说requirejs与seajs,传说中的模块开发,加载器,但它们的最终目标是打包;你们可能听过underscope,那是一个工具集;你们可以听说过ejs,Mustache、HandlebarsJS等模板引擎,它们是用来替代字符串拼接……凡此种种,它们在我们的业务开发中只是很少的部分,带来的帮助也很有限。前端开发,贯彻始终的是如何将后端的数据显示出来,将用户的输入格式化送到后端,都离不开DOM操作,而DOM操作正是许多新手或从后端过来的人所害怕。相比于JS的那点语法,DOM是最庞杂的,三次浏览器大战留下的遗患至今没有消弥,到处是地雷,因此我们怎么放心让新人去趟这祸水呢。jQuery为开发者发一个水泡,让你们淹不死。但最佳方式,就是把这些腐败沼泽都填了。avalon做到了,纯数据操作的时代到来了。
前三节就分别介绍了作用域,ViewModel,绑定属性什么的,它们是我们的主角。其中ViewModel是我们操作的主体,绑定属性是让我们脱离DOM操作的关键。所有对ViewModel的操作,最终交由绑定属性实现各种DOM功能。DOM功能是一个很范的概念,比如添加删除类名,移除节点,让某个元素看不见,为元素添加某个属性或某个事件……今天我们介绍的就是最常用数据填充功能,让后端的数据在页面展示出来。MVVM是如此强大,估计今明年,你们会越来越频繁地看到有关前端MVVM的主题分题,PPT。作为一个简单的示例,它们务必包含数据填充功能的展示。
数据填充是avalon最简单的功能,将数据打印到页面上。这是所有后端模板最基本的功能,然后加上each, if, include等语法,实现更精细的制定。avalon通过绑定属性,其实将整个页面变成一个动态模板(详看这里)。将数据输出到页面涉及到以下指令。
- {{prop}}
- {{prop|html}}
- ms-text
- ms-html
- ms-value
- ms-duplex
{{prop}}是最简单实用的指令,什么helloworld用它做最适合了。
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<script src="avalon.js"></script>
<script>
avalon.define({
$id: "test",
word: "Hello Avalon"
})
</script>
</head>
<body>
<div ms-controller="test">
<h1>{{word}}!!!!!</h1>
</div>
</body>
</html>
{{prop | html}}其实是加一个过滤器,也只有文本节点中的插值表达式可以加各种过滤器实现各种功能。html过滤器就是将此字符串转换HTML节点再插入当前位置。不过这个{{prop|html}},框架是对它开了小灶,允许它本来就是一个元素节点或NodeList。
ms-text与ms-html其实就是{{prop}}、{{prop|html}}的真身,框架内部都是走同一处理函数。不过ms-text、 ms-html作为一个绑定属性,必须附于元素节点之上,因此没有前者那么方便。
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<script src="avalon.js"></script>
<script>
avalon.define("test", function(vm) {
vm.text = "<b> 1111 </b>"
})
</script>
</head>
<body>
<div ms-controller="test">
<div><em>用于测试是否被测除</em>xxxx{{text}}yyyy</div>
<div><em>用于测试是否被测除</em>xxxx{{text|html}}yyyy</div>
<div ms-text="text"><em>用于测试是否被测除</em>xxxx yyyy</div>
<div ms-html="text"><em>用于测试是否被测除</em>xxxx yyyy</div>
</div>
</body>
</html>
此外,我们还可以通过config方法,更改插值表达式的界定符,因为{{}}可能被其他框架的模板所占用。建议界定符的长度大于1,不要设置为>>这样的位操作符。比如在DOMReady之前,我们调用如下语句:
avalon.config({
interpolate: ["<%", "%>"] // 要求openTag 不等于closeTag就能配置成功
})
像上面那样,由于网速慢把插值表达式暴露出来的问题, 我们可以定义这样一个样式规则进行处理,这有点类于angularjs的ng-cloak指令,在扫描之前起着羞丑布的作用。当扫描过后,框架会去掉绑定属性,及ms-controller、ms-important这两个类名,它们就显示出来了。
.ms-controller, .ms-important{visibility:hidden}
上述四种指令是用在文本节点上,但数据还能通过表单元素的value值显示出来,于是有了ms-value指令。ms-value为了应对复杂的显示,也支持插值表达式,但里面不能使用过滤器。
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<script src="avalon.js"></script>
<script>
avalon.define({
$id: "test",
text: "<b> 1111 </b>"
})
</script>
</head>
<body>
<div ms-controller="test">
<input ms-value="text"/>
<textarea ms-value="xxxxxxxx{{text+'!!'}}yyyyyyyy"/></textarea>
</div>
</body>
</html>
上面的功能,后端模板与前端模板也能做到,但ms-duplex就逆天了。它是avalon实现双向绑定的一个重要绑定。双向绑定通俗说,当我们修改ViewModel的属性,通过Object.defineProperty重写属性的setter,getter同步视图,而在视图上偷偷绑定一些input、click、change事件,将元素的value同步到ViewModel上。ms-duplex就是这样干,也意味着它只对表单元素生效。avalon为文本域,文本区,密码域这三个控件绑定了input事件,换言之,用户每改一个字符都会立即发生同步,当然用户可以在元素定义data-duplex-event=”change”属性,就可以改成change事件。对于单选框,复选框,下拉条是绑定了change事件。
在IE6-8下,没有input事件,avalon使用onpropertychange事件,单选框复选框的change事件有BUG,改用click事件,总而言之,avalon设法让旧式IE与W3C浏览器保持一致。
如果用户想在内容发生改变后执行某一回调,avalon也提供了data-duplex-changed回调。此外,用户也可以在VM上使用$watch回调进校正。因此,有了ms-duplex做数据验证是非常简单的。
我们还可以在元素节点上定义data-duplex-observe=”false”来禁止双向同步。
ms-duplex还可以接第三个参数,总括起来,它们的语法如下:
ms-duplex=”prop”
当元素为text, password, textarea时,要求prop为一个字符串,当我们改动它的内容时,avalon就会将此元素的value值赋给prop(在默认情况下,是使用input事件进行绑定,即每改动一个字符,都会进行同步,大家也可以指定data-duplex-event="change",改用change事件进行绑定)
当元素为radio时,要求prop为一个布尔, 当我们改动它的内容时,avalon就会将此元素的checked值(布尔)赋给prop
当元素为checkbox时,要求prop为一个数组, 当我们改动它的内容时,avalon就会将此元素的value值push进prop
当元素为select时,要求prop为一个字符串或数组(视multiple的值), 当我们选中它的某一个项时,avalon就会将此option元素的value值或text值(没有value时)push进prop。
ms-duplex-text=”prop”
只能用于radio,用于模拟text控件的行为, 要求prop为一个字符串,当我们选中某一个radio时,avalon就会将此元素的value值赋给prop 用于实现多选一。
ms-duplex-radio=”prop”
只能用于checkbox,用于模拟radio控件的行为, 要求prop为一个布尔,当我们选中某一个checkbox时,avalon就会将此元素的checked值(布尔)赋给prop 多用于实现GRID中的全选/全不选功能
ms-duplex-bool=”prop”
只能用于radio, 要求prop为一个布尔,并且元素的value为“true”或“false”,当我们选中某一个radio时,avalon就会将此元素的value转换为布尔,赋给对应的prop。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="avalon.js"></script>
<script>
avalon.define({
$id: "test",
aaa: {
xxx: "444",
yyy: "555"
},
bbb: "yyy",
zzz: "text"
})
</script>
</head>
<body ms-controller="test">
<input ms-duplex="aaa['xxx']"><br/>
<input ms-duplex="aaa[bbb]"><br/>
<input ms-duplex="zzz" ms-data-duplex-observe="zzz"/>当这里的值变成false,就会禁止双向同步
<p>{{aaa.xxx}}</p>
<p>{{aaa.yyy}}</p>
<p>{{zzz}}</p>
</body>
</html>
这里有更多ms-duplex的例子。弄懂它们就可以处理大多数表单需求了,然后你就会觉得生活变美好了一些。这快感正如我们一开始从原生JS转到jQuery的那样。时代总是在进步的,早期了解MVVM,早期摆脱DOM的桎梏!
迷你MVVM框架 avalonjs 学习教程4、数据填充的更多相关文章
- 迷你MVVM框架 avalonjs 学习教程19、avalon历史回顾
avalon最早发布于2012.09.15,当时还只是mass Framework的一个模块,当时为了解决视图与JS代码的分耦,参考knockout开发出来. 它的依赖收集机制,视图扫描,绑定的命名d ...
- 迷你MVVM框架 avalonjs 学习教程1、引入avalon
avalon是国内最强大的MVVM框架,没有之一,虽然淘宝KISSY团队也搞了两个MVVM框架,但都无疾而终.其他的MVVM框架都没几个.也只有外国人与像我这样闲的架构师才有时间钻研这东西.我很早之前 ...
- 迷你MVVM框架 avalonjs 学习教程18、一步步做一个todoMVC
大凡出名的MVC,MVVM框架都有todo例子,我们也搞一下看看avalon是否这么便宜. 我们先从react的todo例子中扒一下HTML与CSS用用. <!doctype html> ...
- 迷你MVVM框架 avalonjs 学习教程3、绑定属性与扫描机制
在MVVM框架中,你都会看到页面定了许多奇怪的属性,比如knockout的data-☆,angular的ng-☆,avalon的ms-☆,此外还有一些只写文本节点上的双花括号,它们统称为指令.ms-☆ ...
- 迷你MVVM框架 avalonjs 学习教程12、数据联动
在许多表单应用,我们经常遇到点击一个复选框(或下拉框)会引发旁边的复选框(或下拉框)发生改变,这种联动效果用avalon来做是非常简单的.在avalon里,存在各种绑定回调与$watch回调,完全满足 ...
- 迷你MVVM框架 avalonjs 学习教程7、数据缓存
jQuery的许多功能都可以通过avalon的绑定属性来处理,如click方法对应ms-click,css方法对应ms-css,toggle方法对应ms-visible,它的数据缓存功能avalon也 ...
- 迷你MVVM框架 avalonjs 学习教程20、路由系统
SPA的成功离开不这三个东西,分层架构,路由系统,储存系统.分层架构是我们组织复杂代码的关键,这里特指MVVM的avalon:路由系统是将多个页面压缩在一个页面的关键:储存系统特指本地储存,是安全保存 ...
- 迷你MVVM框架 avalonjs 学习教程11、循环操作
avalon是通过ms-repeat实现对一组数据的批量输出.这一组数据可以是一个数组,也可以是一个哈希(或叫对象).我们先从数组说起吧. 第二节就说,凡是定义在VM中的数组,如果没有以$开头或者没放 ...
- 迷你MVVM框架 avalonjs 学习教程2、模块化、ViewModel、作用域
一个项目是由许多人分工写的,因此必须要合理地拆散,于是有了模块化.体现在工作上,PM通常它这为某某版块,某某频道,某某页面.某一个模块,必须是包含其固有的数据,样式,HTML与处理逻辑.在jQuery ...
随机推荐
- 018PHP基础知识——函数(一)
<?php /** *函数:一部分可重复执行的代码段,多次执行一次编译 * 特点: * 1.减少程序运行的复杂性 * 2.提高程序的可靠性 * 3.提高软件的开发效率 * 4.提高程序的维护性 ...
- [Java] Eclipse下导入外部jar包的3种方式
我们在用Eclipse开发程序的时候,经常要用到第三方jar包.引入jar包不是一个小问题,由于jar包位置不清楚,而浪费时间.下面配图说明3种Eclipse引入jar包的方式. 1.最常用的普通 ...
- Big Table中文翻译
题记:google 的成功除了一个个出色的创意外,还因为有 Jeff Dean 这样的软件架构天才. 官方的 Google Reader blog 中有对BigTable 的解释.这是Google 内 ...
- 我的octopress配置
在github上用octopress搭建了自己的blog,octopress号称是"专门给黑客打造的博客(A blogging framework for 把hackers)",使 ...
- 【LeetCode 232_数据结构_队列_实现】Implement Queue using Stacks
class Queue { public: // Push element x to the back of queue. void push(int x) { while (!nums.empty( ...
- JMeter VS LoadRunner
对比项 JMeter LoadRunner 安装 简单,下载解压即可 复杂,安装包大于1GB,安装时间较久 录制/回放模式 支持 支持 测试协议 偏少,但用户可自行拓展 较多,用户不可自行拓展 分布式 ...
- PyalgoTrade 优化(六)
满足优化器组件.这个想法很简单: 有一个服务器负责: 提供数据来运行策略. 提供运行策略的参数. 记录每个工作线程的策略结果. 有多名工作人员负责: 使用服务器提供的数据和参数运行策略. 为了说明这一 ...
- java利用freemarker导出world
一.简单导出(不含循环导出) 1.新建一个word文件.如下图: 2.使用word将文件另存为xml的格式 3.编辑xml文件内容,将'用户名'替换成-> ${username}.'简介'替换成 ...
- [BZOJ4802]欧拉函数
bzoj description 给出\(n\),求\(\varphi(n)\).\(n\le10^{18}\) sol \(Pollard\ Rho\),存个代码. code #include< ...
- C#对象的三种序列化
要让一个对象支持.Net序列化服务,用户必须为每一个关联的类加上[Serializable]特性.如果类中有些成员不适合参与序列化(比如:密码字段),可以在这些域前加上[NonSerialized]特 ...