迷你MVVM框架 avalonjs 学习教程21、双向绑定链
avalon的双向绑定机制,是通过一条依赖链实现。此依赖链最底层是监控属性、监控数组,中层是计算属性、监控函数,再上点是求值函数,最上层是视图刷新函数。
所谓计算属性,监控属性,监控函数属性,我们改变它们的值,它们会引发视图变化;而监控数组,是我们调用它的一些方法,也会引发视图变化。
- var vm = avalon.define({
- a: "这是监控属性",
- $b: "这是非监控属性",
- $skipArray: ["c", "d"],
- c: "位于$skipArray里,因此也是非监控属性",
- d: "位于$skipArray里,因此也是非监控属性",
- obj: {//这个obj是一个子VM
- xx: "xxx"
- },
- fn: function() {
- alert(1)//这里面没有vm的监控属性(仅指其第一层属性),因此是一个普通函数
- },
- fn2: function() {
- return vm.a //这里面有vm的监控属性(仅指其第一层属性),因此是一个监控函数
- },
- fn3: function() {
- return vm.fn2()//fn2是方法而不是监控属性,因此也是一个普通函数
- },
- array: [1, 2, 3], //这是一个监控数组
- computed: {//这是一个计算属性,因此它有一个get方法,this指向vm
- get: function() {
- return this.a + this.$b
- }
- },
- computed2: {//这是一个计算属性,因此它有get,set方法
- get: function() {
- return this.a + "!!!"
- },
- set: function(v) {
- this.a = v
- }
- },
- ccc: {//这一个普通的对象,构成一个子VM,因为计算属性只允许最多有两个方法,不能出现第三个属性
- get: function() {
- return this.a + "!!!"
- },
- set: function(v) {
- this.a = v
- },
- host: {}
- }
- })
为了性能起见,我们需要将一些属性变成不可监控。这有两个途径,在属性名或方法名前加一个$,或者把属性名放到$skipArray数组里。
监控属性,计算属性,监控属性什么都是位于VM中;而最上面两层是位于视图,通过分解绑定属性,推断出来。比如说ms-text=”aaa”,我们从属性名得到其视图刷新函数(所有视图刷新函数都定义在 avalon.bindingExecutors对象上),求值函数是通过内部的parseExpr方法编译出来。
- <!DOCTYPE html>
- <html>
- <head>
- <title>TODO supply a title</title>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width">
- <script src="avalon.js" type="text/javascript"></script>
- <script>
- vmodel = avalon.define({
- $id: "test",
- a: 1,
- b: 2,
- fn: function() {
- return (parseFloat(vmodel.a) || 0) + (parseFloat(vmodel.b) || 0)
- }
- })
- </script>
- </head>
- <body ms-controller="test">
- <div><input ms-duplex="a"/>{{a}}</div>
- <div><input ms-duplex="b"/>{{b}}</div>
- <div>{{fn()}}</div>
- </body>
- </html>
- <!DOCTYPE html>
- <html>
- <head>
- <title>ms-class</title>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
- <script src="avalon.js"></script>
- <style>
- .green{
- background: green;
- }
- </style>
- <script type="text/javascript">
- var model = avalon.define({
- $id: "test",
- array: [],
- add: function(){
- model.array.push(1)
- },
- remove: function(){
- model.array.pop()
- }
- })
- </script>
- </head>
- <body ms-controller="test" >
- <div ms-class="green: array.length" style="width:400px;height:200px">
- <button ms-click="add" type="button">add</button><button ms-click="remove" type="button">remove</button>
- </div>
- </body>
- </html>
一般情况下,都是上层依赖下层,下层发生改变,就会自动向上冒泡,到视图刷新函数这一层,实现视图的改变,只有一个例外,就是ms-duplex。它会偷偷 在视图上绑定一些事件,通过监听表单元素的值,将它直接同步到下方的监控属性与计算属性。
迷你MVVM框架 avalonjs 学习教程21、双向绑定链的更多相关文章
- 迷你MVVM框架 avalonjs 学习教程3、绑定属性与扫描机制
在MVVM框架中,你都会看到页面定了许多奇怪的属性,比如knockout的data-☆,angular的ng-☆,avalon的ms-☆,此外还有一些只写文本节点上的双花括号,它们统称为指令.ms-☆ ...
- 迷你MVVM框架 avalonjs 学习教程19、avalon历史回顾
avalon最早发布于2012.09.15,当时还只是mass Framework的一个模块,当时为了解决视图与JS代码的分耦,参考knockout开发出来. 它的依赖收集机制,视图扫描,绑定的命名d ...
- 迷你MVVM框架 avalonjs 学习教程22、avalon性能大揭密
avalon之所以能在页面处理1W个绑定(angular对应的数字是2000),出于两个重要设计--基于事件驱动的双向绑定链及智能CG回收机制. avalon的双向绑定链是通过Object.defin ...
- 迷你MVVM框架 avalonjs 学习教程18、一步步做一个todoMVC
大凡出名的MVC,MVVM框架都有todo例子,我们也搞一下看看avalon是否这么便宜. 我们先从react的todo例子中扒一下HTML与CSS用用. <!doctype html> ...
- 迷你MVVM框架 avalonjs 学习教程4、数据填充
MVVM是前端的究极解决方案,你们可能用过jQuery,但那个写的代码不易维护:你们可以听过说requirejs与seajs,传说中的模块开发,加载器,但它们的最终目标是打包:你们可能听过unders ...
- 迷你MVVM框架 avalonjs 学习教程1、引入avalon
avalon是国内最强大的MVVM框架,没有之一,虽然淘宝KISSY团队也搞了两个MVVM框架,但都无疾而终.其他的MVVM框架都没几个.也只有外国人与像我这样闲的架构师才有时间钻研这东西.我很早之前 ...
- 迷你MVVM框架 avalonjs 学习教程20、路由系统
SPA的成功离开不这三个东西,分层架构,路由系统,储存系统.分层架构是我们组织复杂代码的关键,这里特指MVVM的avalon:路由系统是将多个页面压缩在一个页面的关键:储存系统特指本地储存,是安全保存 ...
- 迷你MVVM框架 avalonjs 学习教程16、过滤器
avalon的过滤器是参考自angular与rivets.它也被称做管道文本过滤器,它的处理对象只能是文本(字符串),它只能用在文本绑定中,并且只能是双花括号形式.下面是各大家的过滤器比较: rive ...
- 迷你MVVM框架 avalonjs 学习教程11、循环操作
avalon是通过ms-repeat实现对一组数据的批量输出.这一组数据可以是一个数组,也可以是一个哈希(或叫对象).我们先从数组说起吧. 第二节就说,凡是定义在VM中的数组,如果没有以$开头或者没放 ...
随机推荐
- Flask请求处理流程(request)[待续]
WSGI简介 WSGI(全称Web Server Gateway Interface),是为 Python 语言定义的Web服务器和Web应用程序之间的一种简单而通用的接口,它封装了接受HTTP请求. ...
- win7 任务计划运行批处理,不能正常运行,需用绝对路径
一段批处理在WIN XP下用任务计划可以正常运行: rar.exe u -m3 -s -r -o+ -x*.db -x*.zip -x*.rar zmv9netSrc.rar "Source ...
- Mybatis常见面试题 一
1.#{}和${}的区别是什么? 注:这道题是面试官面试我同事的. 答:${}是Properties文件中的变量占位符,它可以用于标签属性值和sql内部,属于静态文本替换,比如${driver}会被静 ...
- js例子记载
1.获取项目路径的,不一定有用,仅作参考用: function getRootPath() { var curWwwPath = window.document.location.href; //&q ...
- CentOS7 安装supervisor守护进程管理器
supervisor没有发布在标准的CentOS源在,需要安装epel源.这种方式安装的可能不是最新版本,但比较方便,安装完成之后,配置文件会自动帮你生成. 默认配置文件:/etc/superviso ...
- php 流程控制switch实例
switch允许对一个标量(表达式)的多个可能结果做选择. 语法: switch (expr) { case result1: statement1 break; case result2: stat ...
- javascript变量作用域 — 全局变量
javascript中,如果没有用var 声明一个变量,则该变量会被自动创建在全局作用域中,即使你是在某个函数中创建的,它也会成为全局变量,从而可以被另一个函数调用.
- ORM创建 脚本运行
- springboot根据不同的条件创建bean,动态创建bean,@Conditional注解使用
这个需求应该也比较常见,在不同的条件下创建不同的bean,具体场景很多,能看到这篇的肯定懂我的意思. 倘若不了解spring4.X新加入的@Conditional注解的话,要实现不同条件创建不同的be ...
- 配置IIS,以在局域网内访问发布的web站点
在windows 7或win8 中 配置IIS, 以在局域网内访问自己发布的web 网站或应用程序.主要配置步骤如下: 1. 打开 win7 或 win8 控制面板,选择: 打开或关闭windws 功 ...