�Regular里所有的绑定都与表达式有关,表达式编译结果是一个表达式对象, 熟悉本章内容可以帮助你更好的理解Regular内部的数据监听原理。
Regular 支持几乎所有 ES5 表达式语法,下列都是合法的表达式
100 + 'b'
.user? 'login': 'logout'
title = title + '1'
!isLogin && this.login()
items[index][this.nav(item.index)].method1()
几个注意点
- 表达式中的
this
指向组件本身 - 数据根路径从
component.data
开始, 即user
其实获取的是component.data.user
- 不支持自增、自减(
++
,--
)以及位操作符&
|
等 - 不支持正则表达式的字面量
- 开放了部分JS内建对象:
- Array Date JSON Math NaN RegExp Object String
- decodeURI decodeURIComponent encodeURI encodeURIComponent
- parseFloat parseInt
除了 ES5 的表达式,Regular 还提供了以下几种表达式类型
脏检查性能依赖于监听器的数量,Regular引入了@()
预发提供了一次绑定功能: 监听器在一次变更后就会被移除。
syntax
@(Expression)
可以在任意的表达式环境使用
@()
(list
,if
... etc)
Example
<div>{ @(title) }</div> // the interpolation only trigger once
{#if @(test)} // only test once
//...
{/if}
{#list @(items) as item} // only trigger once
//...
{/list}
- 你也可以在
$watch
使用@()
var component = new Regular({
data: {
user: {}
}
});
var i = 0;
component.$watch("@(user.name)", function(){
i++ // only trigger once
});
component.$update("user.name", 1);
component.$update("user.name", 2);
// update twice but trigger once
alert(i === 1);
如上例所示,由于『脏了一次就被被抛弃』, 如果值后续继续变化,会导致UI与数据不同步。
参考
syntax
Expression| fitlerName: arg1, arg2,... argN
Example
假设已注册 format
过滤器
<div>{list|format: 'yy-MM-dd'}</div>
参考指南
Range 即数组的简写模式
Syntax:
start..end
Example
1..3 === [1,2,3]
在动态模板中,如果抛出所有JS中常见的 xx of undefined
的错误,整个系统会变得相当脆弱。Regular 抑制了这类错误中安全的部分,并使用undefined代替
new Regular({
template: "<div>{blog.user.name}</div>"
})
// => <div></div>
如果是方法不存在产生的错误,Regular 仍然会抛出,这属于「非安全」的错误
new Regular({
template: "<div>{this.methodNoFound(blog.user.name)}</div>"
})
其中blog.user.name
错误被抑制,而this.methodNoFound
的未定义错误会被抛出
理解表达式对象,可以帮助你使用表达式
表达式在编译后会通过new Function
编译为一个 表达式对象 ,对象包含以下两个关键方法
-
get(context)
即表达式的求值函数,函数需要传入context(Component实例)参数
Regular的脏检查即通过比较get两次返回是否不同来判断数据是否变动。
example:
// create expression var component = new Regular({ data: { user: 'leeluolee', age: 20 } }); var expr = component.$expression("user + ':' + (age - 10)") alert(expr.get(component) === "leeluolee:10" ) //true
-
set(context, value) *此函数不一定存在
如果表达式是一个合法的LeftHandSideExpression,Regular会提取set函数,用来赋值,set函数通常用于实现双向绑定。
// component as context var component = new Regular({ data: { users: [ {name: 'leeluolee'}, {name: 'luobo'} ], index:0 } }); var expr = component.$expression('users[index].name') expr.set(component, 'daluobo'); alert(component.data.users[0].name === 'daluobo') // true
可以提取出
set
函数的表达式,我们称此表达式是 setable 的,如果一个不是__setable__的表达式应用与双向绑定(如 r-model)结合使用,将不能得到应有效果。
并不是所有表达式都可以提取出set,即代表了不是所有表达式都能完成双向绑定,比如表达式
「a+b」
,显然虽然我们可以获取它的值,但是我们无从知晓如何去设置a和b的值。
文档中,标记为Expression
类型的场景都可以使用表达式。